/*
 * Copyright 2008 sempr <iamsempr@gmail.com>
 *
 * Refacted and modified by zhblue<newsclan@gmail.com>
 * Bug report email newsclan@gmail.com
 *
 *
 * This file is part of HUSTOJ.
 *
 * HUSTOJ is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * HUSTOJ is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with HUSTOJ. if not, see <http://www.gnu.org/licenses/>.
 */

#include <stdio.h>
#include <syslog.h>
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <dirent.h>
#include <unistd.h>
#include <time.h>
#include <stdarg.h>
#include <ctype.h>
#include <sys/wait.h>
#include <sys/ptrace.h>
#include <sys/types.h>
#include <sys/user.h>
#include <sys/syscall.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <sys/signal.h>
#include <sys/stat.h>
#include <unistd.h>
#ifdef OJ_USE_MYSQL
#include <mysql/mysql.h>
#endif
#include <assert.h>
#include "okcalls.h"
#include <iostream>
#include <filesystem>

#include <cstdlib>
#include <string>
#include <cstring>

#include <fstream>
#include <cmath>

#define STD_MB 1048576LL
#define STD_T_LIM 2
#define STD_F_LIM (STD_MB << 7) 
#define STD_M_LIM (STD_MB << 7) 
#define BUFFER_SIZE 4096		
#define LOCKMODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)

#define OJ_WT0 0 // Submission Queue
#define OJ_WT1 1 // Rejudge Queue
#define OJ_CI 2   // Compiling (Task has been dispatched)
#define OJ_RI 3   // Running
#define OJ_AC 4  // Answer Correct
#define OJ_PE 5  // Format Error
#define OJ_WA 6  // Wrong Answer
#define OJ_TL 7  // Time Limit Exceeded
#define OJ_ML 8  // Memory Limit Exceeded
#define OJ_OL 9  // Output Limit Exceeded
#define OJ_RE 10 // Runtime Error
#define OJ_CE 11 // Compile Error
#define OJ_CO 12 // Compile Complete
#define OJ_TR 13 // Test Run Completed
#define OJ_MC 14 // Waiting for Judge's Manual Confirmation

#ifdef __arm__ 
struct user_regs_struct
{
	long uregs[18];
};

#define ARM_r7 uregs[7]
#define ARM_ORIG_r0 uregs[17]

#define REG_SYSCALL ARM_r7
#endif

#ifdef __aarch64__ 
#define NT_PRSTATUS 1
#define NT_ARM_SYSTEM_CALL 0x404
#define ARM_cpsr uregs[16]
#define ARM_pc uregs[15]
#define ARM_lr uregs[14]
#define ARM_sp uregs[13]
#define ARM_ip uregs[12]
#define ARM_fp uregs[11]
#define ARM_r10 uregs[10]
#define ARM_r9 uregs[9]
#define ARM_r8 regs[8]
#define ARM_r7 uregs[7]
#define ARM_r6 uregs[6]
#define ARM_r5 uregs[5]
#define ARM_r4 uregs[4]
#define ARM_r3 uregs[3]
#define ARM_r2 uregs[2]
#define ARM_r1 uregs[1]
#define ARM_r0 uregs[0]
#define ARM_ORIG_r0 uregs[17]
#define PTRACE_GETREGS PTRACE_GETREGSET
#define PTRACE_SETREGS PTRACE_SETREGSET
#define REG_SYSCALL regs[18]

#endif

#ifdef __mips__ 
typedef unsigned long long uint64_t;
struct user_regs_struct
{
	uint64_t uregs[38];
};

#define REG_V0 2
#define REG_A0 4

#define mips_REG_V0 uregs[REG_V0]
#define REG_SYSCALL mips_REG_V0

#endif

#ifdef __i386 
#define REG_SYSCALL orig_eax
#define REG_RET eax
#define REG_ARG0 ebx
#define REG_ARG1 ecx
#endif

#ifdef __x86_64__ 
#define REG_SYSCALL orig_rax
#define REG_RET rax
#define REG_ARG0 rdi
#define REG_ARG1 rsi

#endif

static int DEBUG = 0;
static int PERFORMANCE = 0;
static char host_name[BUFFER_SIZE / 10];								  
static int port_number;													  
static char user_name[BUFFER_SIZE / 10];								  
static char password[BUFFER_SIZE / 10];									  
static char db_name[BUFFER_SIZE / 10];									 
static char oj_home[BUFFER_SIZE / 10];									  
static char data_list[BUFFER_SIZE][BUFFER_SIZE];						 
static int data_list_len = 0;											 
static char lock_file[BUFFER_SIZE] = "/home/judge/run0/judge_client.pid"; 

static int max_running;
static int sleep_time;
static int java_time_bonus = 5;
static int java_memory_bonus = 512;
static char java_xms[BUFFER_SIZE / 10];
static char java_xmx[BUFFER_SIZE / 10];
static int sim_enable = 0;
static int oi_mode = 0;
static int full_diff = 0;
static int raw_text_diff = 1;
static int use_max_time = 0;
static int time_limit_to_total = 1;
static int total_time = 0;

static int http_judge = 0;
static int copy_data = 0;
static char http_baseurl[BUFFER_SIZE / 10];
static char http_apipath[BUFFER_SIZE / 10];
static char http_loginpath[BUFFER_SIZE / 10];
static char http_username[BUFFER_SIZE / 10];
static char http_password[BUFFER_SIZE / 10];
static int http_download = 1;
static double cpu_compensation = 1.0;

static int shm_run = 0;

static char record_call = 0;
static int use_ptrace = 1;
static int ignore_esol = 1;
static int compile_chroot = 0;
static int turbo_mode = 0;
static int python_free = 0;
static int use_docker = 0;
static const char *tbname = "solution";
static char cc_opt[BUFFER_SIZE / 10];
static char cc_std[BUFFER_SIZE / 10];
static char cpp_std[BUFFER_SIZE / 10];
static int auto_result = OJ_AC;

int num_of_test = 0;

static int py2 = 1; // caution: py2=1 means default using py3

#define ZOJ_COM

#ifdef _mysql_h
MYSQL *conn;
#endif
static char jresult[15][4] = {"PD", "PR", "CI", "RJ", "AC", "PE", "WA", "TLE", "MLE", "OLE", "RE", "CE", "CO", "TR", "MC"};
static char lang_ext[22][8] = {"c", "cc", "pas", "java", "rb", "sh", "py",
							   "php", "pl", "cs", "m", "bas", "scm", "c", "cc", "lua", "js", "go", "sql", "f95", "m", "cob"};

int lockfile(int fd)
{
	struct flock fl;
	fl.l_type = F_WRLCK;
	fl.l_start = 0;
	fl.l_whence = SEEK_SET;
	fl.l_len = 0;
	return (fcntl(fd, F_SETLK, &fl));
}

int already_running()
{
	int fd;
	char buf[16];
	fd = open(lock_file, O_RDWR | O_CREAT, LOCKMODE);
	if (fd < 0)
	{
		if (DEBUG)
			printf("%s open fail.\n", lock_file);
		exit(1);
	}
	if (lockfile(fd) < 0)
	{
		if (errno == EACCES || errno == EAGAIN)
		{
			close(fd);
			return 1;
		}

		if (DEBUG)
			printf("%s lock fail.\n", lock_file);
		exit(1);
	}
	if (ftruncate(fd, 0))
		printf("close file fail 0 \n");
	sprintf(buf, "%d", getpid());
	if (write(fd, buf, strlen(buf) + 1) >= BUFFER_SIZE)
		printf("buffer size overflow!...\n");
	return (0);
}

void print_arm_regs(long long unsigned int *d)
{
	for (int i = 0; i < 32; i++)
	{
		printf("[%d]:%lld ", i, d[i] % CALL_ARRAY_SIZE);
	}
	printf("\n");
}

int data_list_has(char *file)
{
	for (int i = 0; i < data_list_len; i++)
	{
		if (strcmp(data_list[i], file) == 0)
			return 1;
	}
	return 0;
}

int data_list_add(char *file)
{
	if (data_list_len < BUFFER_SIZE - 1)
	{
		strcpy(data_list[data_list_len], file);
		data_list_len++;
		return 0;
	}
	else
	{
		return 1;
	}
}

long get_file_size(const char *filename)
{
	struct stat f_stat;

	if (stat(filename, &f_stat) == -1)
	{
		return 0;
	}

	return (long)f_stat.st_size;
}

void write_log(const char *_fmt, ...)
{
	va_list ap;
	char fmt[BUFFER_SIZE];
	strncpy(fmt, _fmt, BUFFER_SIZE);
	char buffer[BUFFER_SIZE];
	if (DEBUG)
		printf("fp debug:%s\n", buffer);
	sprintf(buffer, "%s/log/client.log", oj_home);
	FILE *fp = fopen(buffer, "ae+");
	if (fp == NULL)
	{
		fprintf(stderr, "Failed log message: %s\n", fmt);
		fprintf(stderr, "fp null %s/log/client.log openfile error!\n", oj_home);
		exit(-6);
	}
	va_start(ap, _fmt);
	// l =
	vsprintf(buffer, fmt, ap);
	fprintf(fp, "%s\n", buffer);
	if (DEBUG)
		printf("%s\n", buffer);
	va_end(ap);
	fclose(fp);
}

int execute_cmd(const char *fmt, ...) 
{
	char cmd[BUFFER_SIZE];

	int ret = 0;
	va_list ap;

	va_start(ap, fmt);
	vsprintf(cmd, fmt, ap);
	if (DEBUG)
		write_log("%s\n", cmd);
	ret = system(cmd);
	va_end(ap);
	return ret;
}

const int call_array_size = CALL_ARRAY_SIZE;
unsigned int call_id = 0;
int call_counter[call_array_size] = {0};
static char LANG_NAME[BUFFER_SIZE];

void init_syscalls_limits(int lang) 
{
	int i;
	memset(call_counter, 0, sizeof(call_counter));
	if (DEBUG)
		write_log("init_call_counter:%d", lang);
	if (record_call)
	{ // recording for debuging
		for (i = 0; i < call_array_size; i++)
		{
			call_counter[i] = 0;
		}
	}
	else if (lang <= LANG_CPP || lang == LANG_CLANG || lang == LANG_CLANGPP)
	{ // C & C++
		for (i = 0; i == 0 || LANG_CV[i]; i++)
		{
			call_counter[LANG_CV[i]] = HOJ_MAX_LIMIT;
		}
	}
	else if (lang == LANG_PASCAL)
	{ // Pascal
		for (i = 0; i == 0 || LANG_PV[i]; i++)
			call_counter[LANG_PV[i]] = HOJ_MAX_LIMIT;
	}
	else if (lang == LANG_JAVA)
	{ // Java
		for (i = 0; i == 0 || LANG_JV[i]; i++)
			call_counter[LANG_JV[i]] = HOJ_MAX_LIMIT;
	}
	else if (lang == LANG_RUBY)
	{ // Ruby
		for (i = 0; i == 0 || LANG_RV[i]; i++)
			call_counter[LANG_RV[i]] = HOJ_MAX_LIMIT;
	}
	else if (lang == LANG_BASH)
	{ // Bash
		for (i = 0; i == 0 || LANG_BV[i]; i++)
			call_counter[LANG_BV[i]] = HOJ_MAX_LIMIT;
	}
	else if (lang == LANG_PYTHON)
	{ // Python
		for (i = 0; i == 0 || LANG_YV[i]; i++)
			call_counter[LANG_YV[i]] = HOJ_MAX_LIMIT;
	}
	else if (lang == LANG_PHP)
	{ // php
		for (i = 0; i == 0 || LANG_PHV[i]; i++)
			call_counter[LANG_PHV[i]] = HOJ_MAX_LIMIT;
	}
	else if (lang == LANG_PERL)
	{ // perl
		for (i = 0; i == 0 || LANG_PLV[i]; i++)
			call_counter[LANG_PLV[i]] = HOJ_MAX_LIMIT;
	}
	else if (lang == LANG_CSHARP)
	{ // mono c#
		for (i = 0; i == 0 || LANG_CSV[i]; i++)
			call_counter[LANG_CSV[i]] = HOJ_MAX_LIMIT;
	}
	else if (lang == LANG_OBJC)
	{ // objective c
		for (i = 0; i == 0 || LANG_OV[i]; i++)
			call_counter[LANG_OV[i]] = HOJ_MAX_LIMIT;
	}
	else if (lang == LANG_FREEBASIC)
	{ // free basic
		for (i = 0; i == 0 || LANG_BASICV[i]; i++)
			call_counter[LANG_BASICV[i]] = HOJ_MAX_LIMIT;
	}
	else if (lang == LANG_SCHEME)
	{ // scheme guile
		for (i = 0; i == 0 || LANG_SV[i]; i++)
			call_counter[LANG_SV[i]] = HOJ_MAX_LIMIT;
	}
	else if (lang == LANG_LUA)
	{ // lua
		for (i = 0; i == 0 || LANG_LUAV[i]; i++)
			call_counter[LANG_LUAV[i]] = HOJ_MAX_LIMIT;
	}
	else if (lang == LANG_JS)
	{ // nodejs
		for (i = 0; i == 0 || LANG_JSV[i]; i++)
			call_counter[LANG_JSV[i]] = HOJ_MAX_LIMIT;
	}
	else if (lang == LANG_GO)
	{ // go
		for (i = 0; i == 0 || LANG_GOV[i]; i++)
			call_counter[LANG_GOV[i]] = HOJ_MAX_LIMIT;
	}
	else if (lang == LANG_SQL)
	{ // go
		for (i = 0; i == 0 || LANG_SQLV[i]; i++)
			call_counter[LANG_SQLV[i]] = HOJ_MAX_LIMIT;
	}
	else if (lang == LANG_FORTRAN)
	{ // go
		for (i = 0; i == 0 || LANG_FV[i]; i++)
			call_counter[LANG_FV[i]] = HOJ_MAX_LIMIT;
	}
	else if (lang == LANG_MATLAB)
	{ // matlab
		for (i = 0; i == 0 || LANG_MV[i]; i++)
			call_counter[LANG_MV[i]] = HOJ_MAX_LIMIT;
	}
	else if (lang == LANG_COBOL)
	{ // cobol
		for (i = 0; i == 0 || LANG_CBV[i]; i++)
			call_counter[LANG_CBV[i]] = HOJ_MAX_LIMIT;
	}
#ifdef __aarch64__
	if (lang == 3)
		call_counter[220] = 100;
	else
		call_counter[220] = 1;
#else
	call_counter[SYS_execve % call_array_size] = 1;
#endif
	printf("SYS_execve:%d\n", SYS_execve % call_array_size);
}

int after_equal(char *c)
{
	int i = 0;
	for (; c[i] != '\0' && c[i] != '='; i++)
		;
	return ++i;
}

void trim(char *c)
{
	char buf[BUFFER_SIZE];
	char *start, *end;
	strcpy(buf, c);
	start = buf;
	while (isspace(*start))
		start++;
	end = start;
	while (!isspace(*end))
		end++;
	*end = '\0';
	strcpy(c, start);
}

bool read_buf(char *buf, const char *key, char *value)
{
	if (strncmp(buf, key, strlen(key)) == 0)
	{
		strcpy(value, buf + after_equal(buf));
		trim(value);
		if (DEBUG)
			printf("%s=%s\n", key, value);
		return 1;
	}
	return 0;
}

void read_double(char *buf, const char *key, double *value)
{
	char buf2[BUFFER_SIZE];
	if (read_buf(buf, key, buf2))
		if (1 != sscanf(buf2, "%lf", value))
			printf("double value read fail\n");
}

void read_int(char *buf, const char *key, int *value)
{
	char buf2[BUFFER_SIZE];
	if (read_buf(buf, key, buf2))
		if (1 != sscanf(buf2, "%d", value))
			printf("int value read fail\n");
}

FILE *read_cmd_output(const char *fmt, ...)
{
	char cmd[BUFFER_SIZE];

	FILE *ret = NULL;
	va_list ap;

	va_start(ap, fmt);
	vsprintf(cmd, fmt, ap);
	va_end(ap);
	if (DEBUG)
		printf("%s\n", cmd);
	ret = popen(cmd, "r");

	return ret;
}

// read the configue file
void init_judge_conf() 
{
	FILE *fp = NULL;
	char buf[BUFFER_SIZE];
	host_name[0] = 0;
	user_name[0] = 0;
	password[0] = 0;
	db_name[0] = 0;
	port_number = 3306;
	max_running = 3;
	sleep_time = 3;
	strcpy(java_xms, "-Xms32m");
	strcpy(java_xmx, "-Xmx256m");
	strcpy(cc_std, "-std=c99");
	strcpy(cc_opt, "-O2");
	printf("GCC version: %d,%d\n", __GNUC__,__GNUC_MINOR__);
	if (__GNUC__ > 9 || (__GNUC__ == 9 && __GNUC_MINOR__ >= 3))
	{
		// ubuntu20.04 introduce g++9.3
		strcpy(cc_std, "-std=c17");
		strcpy(cpp_std, "-std=c++14"); // CCF NOI change settings for NOIP to C++14 on 2021-9-1
									   // strcpy(cpp_std,"-std=c++17");
	}
	else
	{
		strcpy(cc_std, "-std=c99");
		strcpy(cpp_std, "-std=c++11");
	}
	sprintf(buf, "%s/etc/judge.conf", oj_home);
	fp = fopen("./etc/judge.conf", "re");
	if (fp != NULL)
	{
		while (fgets(buf, BUFFER_SIZE - 1, fp))
		{
			read_buf(buf, "OJ_HOST_NAME", host_name);
			read_buf(buf, "OJ_USER_NAME", user_name);
			read_buf(buf, "OJ_PASSWORD", password);
			read_buf(buf, "OJ_DB_NAME", db_name);
			read_int(buf, "OJ_PORT_NUMBER", &port_number);
			read_int(buf, "OJ_JAVA_TIME_BONUS", &java_time_bonus);
			read_int(buf, "OJ_JAVA_MEMORY_BONUS", &java_memory_bonus);
			read_int(buf, "OJ_SIM_ENABLE", &sim_enable);
			read_buf(buf, "OJ_JAVA_XMS", java_xms);
			read_buf(buf, "OJ_JAVA_XMX", java_xmx);
			read_int(buf, "OJ_HTTP_JUDGE", &http_judge);
			read_buf(buf, "OJ_HTTP_BASEURL", http_baseurl);
			read_buf(buf, "OJ_HTTP_APIPATH", http_apipath);
			read_buf(buf, "OJ_HTTP_LOGINPATH", http_loginpath);
			read_buf(buf, "OJ_HTTP_USERNAME", http_username);
			read_buf(buf, "OJ_HTTP_PASSWORD", http_password);
			read_int(buf, "OJ_HTTP_DOWNLOAD", &http_download);
			read_int(buf, "OJ_OI_MODE", &oi_mode);
			read_int(buf, "OJ_FULL_DIFF", &full_diff);
			read_int(buf, "OJ_RAW_TEXT_DIFF", &raw_text_diff);
			read_int(buf, "OJ_SHM_RUN", &shm_run);
			read_int(buf, "OJ_USE_MAX_TIME", &use_max_time);
			read_int(buf, "OJ_TIME_LIMIT_TO_TOTAL", &time_limit_to_total);
			read_int(buf, "OJ_USE_PTRACE", &use_ptrace);
			read_int(buf, "OJ_IGNORE_ESOL", &ignore_esol);
			read_int(buf, "OJ_COMPILE_CHROOT", &compile_chroot);
			read_int(buf, "OJ_TURBO_MODE", &turbo_mode);
			read_double(buf, "OJ_CPU_COMPENSATION", &cpu_compensation);
			read_int(buf, "OJ_PYTHON_FREE", &python_free);
			read_int(buf, "OJ_COPY_DATA", &copy_data);
			read_int(buf, "OJ_USE_DOCKER", &use_docker);
			read_buf(buf, "OJ_CC_STD", cc_std);
			read_buf(buf, "OJ_CPP_STD", cpp_std);
			read_buf(buf, "OJ_CC_OPT", cc_opt);
			read_int(buf, "OJ_AUTO_RESULT", &auto_result);
		}
		fclose(fp);
	}
	if (use_docker)
	{
		shm_run = 0;
		compile_chroot = 0;
	}
	if (strcmp(http_username, "IP") == 0)
	{
		FILE *fjobs = fopen("/etc/hostname", "r");
		if (1 != fscanf(fjobs, "%s", http_username))
			printf("IP/HOSTNAME read fail...\n");
		fclose(fjobs);
	}
	if (turbo_mode == 2)
		tbname = "solution2";
}

int isInFile(const char fname[])
{
	int l = strlen(fname);
	printf("\nlength:%d\n",l);
	if (l <= 3 || strcmp(fname + l - 3, ".in") != 0){
		printf("\nnot .in\n",l);
		return 0;
	}
	else
	{
		printf("\nis .in\n",l);
		return l - 3;
	}
	
}

int inFile(const struct dirent *dp)
{ 

	int l = strlen(dp->d_name);
	if (DEBUG)
		printf("file name:%s\n", dp->d_name);
	if (DEBUG)
		printf("ext name:%s\n", dp->d_name + l - 3);
    int ret = isInFile(dp->d_name);
	if (DEBUG)
		printf("\t:%d\n", ret);
	return ret;
}

void find_next_nonspace(int &c1, int &c2, FILE *&f1, FILE *&f2, int &ret)
{
	// Find the next non-space character or \n.
	while ((isspace(c1)) || (isspace(c2)))
	{
		if (c1 != c2)
		{
			if (c2 == EOF)
			{
				do
				{
					c1 = fgetc(f1);
				} while (isspace(c1));
				continue;
			}
			else if (c1 == EOF)
			{
				do
				{
					c2 = fgetc(f2);
				} while (isspace(c2));
				continue;
			}
			else if (ignore_esol)
			{
				if (isspace(c1) && isspace(c2))
				{
					while (c2 == '\n' && isspace(c1) && c1 != '\n')
						c1 = fgetc(f1);
					while (c1 == '\n' && isspace(c2) && c2 != '\n')
						c2 = fgetc(f2);
				}
				else
				{
					if (DEBUG)
						printf("%d=%c\t%d=%c", c1, c1, c2, c2);
					;
					ret = OJ_PE;
				}
			}
			else if (!ignore_esol)
			{
				if ((c1 == '\r' && c2 == '\n'))
				{
					c1 = fgetc(f1);
				}
				else if ((c2 == '\r' && c1 == '\n'))
				{
					c2 = fgetc(f2);
				}
				else
				{
					if (DEBUG)
						printf("%d=%c\t%d=%c", c1, c1, c2, c2);
					;
					ret = OJ_PE;
				}
			}
		}
		if (isspace(c1))
		{
			c1 = fgetc(f1);
		}
		if (isspace(c2))
		{
			c2 = fgetc(f2);
		}
	}
}

/***
 int compare_diff(const char *file1,const char *file2){
 char diff[1024];
 sprintf(diff,"diff -q -B -b -w --strip-trailing-cr %s %s",file1,file2);
 int d=system(diff);
 if (d) return OJ_WA;
 sprintf(diff,"diff -q -B --strip-trailing-cr %s %s",file1,file2);
 int p=system(diff);
 if (p) return OJ_PE;
 else return OJ_AC;
 }
 */
const char *getFileNameFromPath(const char *path)
{
	for (int i = strlen(path); i >= 0; i--)
	{
		if (path[i] == '/')
			return &path[i + 1];
	}
	return path;
}


const char* getLastDirectoryName(const char *filepath) {
    char* last_slash = const_cast<char*>(strrchr(filepath, '/'));
    if (last_slash == nullptr) {
        return nullptr;
    }

    char* second_last_slash = nullptr;
    for (char* p = last_slash - 1; p >= filepath; --p) {
        if (*p == '/') {
            second_last_slash = p + 1;
            break;
        }
    }

    if (second_last_slash != nullptr) {
        size_t length = last_slash - second_last_slash;
        char* result = new char[length + 1]; 
        strncpy(result, second_last_slash, length);
        result[length] = '\0'; 
        return reinterpret_cast<const char*>(result);
    } else {
        return nullptr; 
    }
}

void make_diff_out_full(FILE *f1, FILE *f2, int c1, int c2, const char *path, const char *infile, const char *userfile)
{
	execute_cmd("echo '========[%s]========='>>diff.out", getFileNameFromPath(path));
	execute_cmd("echo  '\\n------test in top 100 lines------'>>diff.out");
	execute_cmd("head -100 %s >>diff.out", infile);
	execute_cmd("echo  '\\n------test out top 100 lines-----'>>diff.out");
	execute_cmd("head -100 '%s'>>diff.out", path);
	execute_cmd("echo  '\\n------user out top 100 lines-----'>>diff.out");
	execute_cmd("head -100 %s >>diff.out", userfile);
	execute_cmd("echo  '\\n------diff out 200 lines-----'>>diff.out");
	execute_cmd("diff '%s' %s -y|grep \\||head -200>>diff.out", path, userfile);
	execute_cmd("echo  '\\n=============================='>>diff.out");
}



void make_diff_out_simple(FILE *f1, FILE *f2, int c1, int c2, const char *path, const char *userfile)
{
	execute_cmd("echo '========[%s]========='>>diff.out", getFileNameFromPath(path));
	execute_cmd("echo 'Expected						      |	Yours'>>diff.out");
	execute_cmd("diff '%s' %s -y|head -100>>diff.out", path, userfile);
	execute_cmd("echo '\n=============================='>>diff.out");
}

/*
 * translated from ZOJ judger r367
 * http://code.google.com/p/zoj/source/browse/trunk/judge_client/client/text_checker.cc#25
 */
int compare_zoj(const char *file1, const char *file2, const char *infile, const char *userfile)
{
	int ret = OJ_AC;
	int c1, c2;
	FILE *f1, *f2;
	f1 = fopen(file1, "re");
	f2 = fopen(file2, "re");
	if (!f1 || !f2)
	{
		ret = OJ_RE;
	}
	else
		for (;;)
		{
			// Find the first non-space character at the beginning of line.
			// Blank lines are skipped.
			c1 = fgetc(f1);
			c2 = fgetc(f2);
			find_next_nonspace(c1, c2, f1, f2, ret);
			// Compare the current line.
			for (;;)
			{
				// Read until 2 files return a space or 0 together.
				while ((!isspace(c1) && c1) || (!isspace(c2) && c2))
				{
					if (c1 == EOF && c2 == EOF)
					{
						goto end;
					}
					if (c1 == EOF || c2 == EOF)
					{
						break;
					}
					if (c1 != c2)
					{
						// Consecutive non-space characters should be all exactly the ifconfig|grep 'inet'|awk -F: '{printf $2}'|awk  '{printf $1}'same
						ret = OJ_WA;
						goto end;
					}
					c1 = fgetc(f1);
					c2 = fgetc(f2);
				}
				find_next_nonspace(c1, c2, f1, f2, ret);
				if (c1 == EOF && c2 == EOF)
				{
					goto end;
				}
				if (c1 == EOF || c2 == EOF)
				{
					ret = OJ_WA;
					goto end;
				}

				if ((c1 == '\n' || !c1) && (c2 == '\n' || !c2))
				{
					break;
				}
			}
		}
end:
	if (ret == OJ_WA || ret == OJ_PE)
	{
		if (full_diff)
			make_diff_out_full(f1, f2, c1, c2, file1, infile, userfile);
		else
			make_diff_out_simple(f1, f2, c1, c2, file1, userfile);
	}
	if (f1)
		fclose(f1);
	if (f2)
		fclose(f2);
	return ret;
}

void delnextline(char s[])
{
	int L;
	L = strlen(s);
	while (L > 0 && (s[L - 1] == '\n' || s[L - 1] == '\r'))
		s[--L] = 0;
}

int compare(const char *file1, const char *file2, const char *infile, const char *userfile)
{
#ifdef ZOJ_COM
	// compare ported and improved from zoj don't limit file size
	return compare_zoj(file1, file2, infile, userfile);
#endif
#ifndef ZOJ_COM
	// the original compare from the first version of hustoj has file size limit 
	// and waste memory
	FILE *f1, *f2;
	char *s1, *s2, *p1, *p2;
	int PEflg;
	s1 = new char[STD_F_LIM + 512];
	s2 = new char[STD_F_LIM + 512];
	if (!(f1 = fopen(file1, "re")))
		return OJ_AC;
	for (p1 = s1; EOF != fscanf(f1, "%s", p1);)
		while (*p1)
			p1++;
	fclose(f1);
	if (!(f2 = fopen(file2, "re")))
		return OJ_RE;
	for (p2 = s2; EOF != fscanf(f2, "%s", p2);)
		while (*p2)
			p2++;
	fclose(f2);
	if (strcmp(s1, s2) != 0)
	{
		delete[] s1;
		delete[] s2;

		return OJ_WA;
	}
	else
	{
		f1 = fopen(file1, "re");
		f2 = fopen(file2, "re");
		PEflg = 0;
		while (PEflg == 0 && fgets(s1, STD_F_LIM, f1) && fgets(s2, STD_F_LIM, f2))
		{
			delnextline(s1);
			delnextline(s2);
			if (strcmp(s1, s2) == 0)
				continue;
			else
				PEflg = 1;
		}
		delete[] s1;
		delete[] s2;
		fclose(f1);
		fclose(f2);
		if (PEflg)
			return OJ_PE;
		else
			return OJ_AC;
	}
#endif
}

bool check_login()
{
	const char *cmd =
		" wget --post-data=\"checklogin=1\" --load-cookies=cookie --save-cookies=cookie --keep-session-cookies -q -O - \"%s%s\"";
	int ret = 0;
	FILE *fjobs = read_cmd_output(cmd, http_baseurl, http_apipath);
	if (1 != fscanf(fjobs, "%d", &ret))
		printf("http login fail..");
	pclose(fjobs);

	return ret;
}

void login()
{
	if (!check_login())
	{
		const char *cmd =
			"wget --post-data=\"user_id=%s&password=%s\" --load-cookies=cookie --save-cookies=cookie --keep-session-cookies -q -O - \"%s%s\"";
		FILE *fjobs = read_cmd_output(cmd, http_username, http_password,
									  http_baseurl, http_loginpath);
		pclose(fjobs);
	}
}

#ifdef _mysql_h
void _update_solution_mysql(int solution_id, int cid, int result, double time_lmt, int mem_lmt, int time, int memory,
							int sim, int sim_s_id, double pass_rate)
{
	char sql[BUFFER_SIZE];
	char judger[BUFFER_SIZE / 10];
	int passed_flag = 0;
	mysql_real_escape_string(conn, judger, http_username, strlen(http_username));

	passed_flag = (result == 4) ? 1 : 0;

	if (oi_mode)
	{
		sprintf(sql,
				"UPDATE %s SET result=%d,time=%d,memory=%d,passed_flag=%d,pass_rate=%f,judger='%s',judgetime=now() WHERE solution_id=%d ",
				tbname, result, time, memory, passed_flag, pass_rate, judger, solution_id);
	}
	else
	{
		sprintf(sql,
				"UPDATE %s SET result=%d,time=%d,memory=%d,passed_flag=%d,judger='%s',judgetime=now() WHERE solution_id=%d ",
				tbname, result, time, memory, passed_flag, judger, solution_id);
	}
	printf("sql= %s\n",sql);
	if (mysql_real_query(conn, sql, strlen(sql)))
	{
		//              printf("..update failed! %s\n",mysql_error(conn));
	}
	if (sim)
	{
		sprintf(sql,
				"insert into sim(s_id,sim_s_id,sim) values(%d,%d,%d) on duplicate key update  sim_s_id=%d,sim=%d",
				solution_id, sim_s_id, sim, sim_s_id, sim);
		if (mysql_real_query(conn, sql, strlen(sql)))
		{
			//              printf("..update failed! %s\n",mysql_error(conn));
		}
	}
}
#endif

void _update_solution_http(int solution_id, int cid, int result, double time_lmt, int mem_lmt, int time, int memory,
						   int sim, int sim_s_id, double pass_rate)
{
	const char *cmd =
		" wget --post-data=\"update_solution=1&sid=%d&result=%d&time=%d&memory=%d&sim=%d&simid=%d&pass_rate=%f\" --load-cookies=cookie --save-cookies=cookie --keep-session-cookies -q -O - \"%s%s\"";
	FILE *fjobs = read_cmd_output(cmd, solution_id, result, time, memory, sim,
								  sim_s_id, pass_rate, http_baseurl, http_apipath);
	pclose(fjobs);
}

void update_solution(int solution_id, int cid, int result, double time_lmt, int mem_lmt, int time, int memory, int sim,
					 int sim_s_id, double pass_rate)
{
	if (result == OJ_TL && memory == 0)
		result = OJ_ML;
	if (result == OJ_AC)
		result = auto_result;
	if (http_judge)
	{
		_update_solution_http(solution_id, cid, result, time_lmt, mem_lmt, time, memory, sim, sim_s_id,
							  pass_rate);
	}
	else
	{

#ifdef _mysql_h
		_update_solution_mysql(solution_id, cid, result, time_lmt, mem_lmt, time, memory, sim, sim_s_id,
							   pass_rate);
#endif
	}
}

/* write compile error message back to database */
#ifdef _mysql_h
void _addceinfo_mysql(int solution_id)
{
	char sql[(1 << 16)], *end;
	char ceinfo[(1 << 16)], *cend;
	FILE *fp = fopen("ce.txt", "re");
	snprintf(sql, (1 << 16) - 1, "DELETE FROM compileinfo WHERE solution_id=%d",
			 solution_id);
	mysql_real_query(conn, sql, strlen(sql));
	cend = ceinfo;
	while (fgets(cend, 1024, fp))
	{
		cend += strlen(cend);
		if (cend - ceinfo > 16384)
			break;
	}
	*cend = '\0';
	end = sql;
	strcpy(end, "INSERT INTO compileinfo VALUES(");
	end += strlen(sql);
	*end++ = '\'';
	end += sprintf(end, "%d", solution_id);
	*end++ = '\'';
	*end++ = ',';
	*end++ = '\'';
	end += mysql_real_escape_string(conn, end, ceinfo, strlen(ceinfo));
	*end++ = '\'';
	*end++ = ')';
	*end = 0;
	//      printf("%s\n",ceinfo);
	if (mysql_real_query(conn, sql, end - sql))
		printf("%s\n", mysql_error(conn));
	fclose(fp);
}
#endif

// urlencoded function copied from http://www.geekhideout.com/urlcode.shtml
/* Converts a hex character to its integer value */
char from_hex(char ch)
{
	return isdigit(ch) ? ch - '0' : tolower(ch) - 'a' + 10;
}

/* Converts an integer value to its hex character*/
char to_hex(char code)
{
	static char hex[] = "0123456789abcdef";
	return hex[code & 15];
}

/* Returns a url-encoded version of str */
/* IMPORTANT: be sure to free() the returned string after use */
char *url_encode(char *str)
{
	char *pstr = str, *buf = (char *)malloc(strlen(str) * 3 + 1), *pbuf = buf;
	while (*pstr)
	{
		if (isalnum(*pstr) || *pstr == '-' || *pstr == '_' || *pstr == '.' || *pstr == '~')
			*pbuf++ = *pstr;
		else if (*pstr == ' ')
			*pbuf++ = '+';
		else
			*pbuf++ = '%', *pbuf++ = to_hex(*pstr >> 4), *pbuf++ = to_hex(*pstr & 15);
		pstr++;
	}
	*pbuf = '\0';
	return buf;
}

void _addceinfo_http(int solution_id)
{

	char ceinfo[(1 << 16)], *cend;
	char *ceinfo_encode;
	FILE *fp = fopen("ce.txt", "re");

	cend = ceinfo;
	while (fgets(cend, 1024, fp))
	{
		cend += strlen(cend);
		if (cend - ceinfo > 16384)
			break;
	}
	*cend = '\0';
	fclose(fp);
	ceinfo_encode = url_encode(ceinfo);
	FILE *ce = fopen("ce.post", "we");
	fprintf(ce, "addceinfo=1&sid=%d&ceinfo=%s", solution_id, ceinfo_encode);
	fclose(ce);
	free(ceinfo_encode);

	const char *cmd =
		" wget --post-file=\"ce.post\" --load-cookies=cookie --save-cookies=cookie --keep-session-cookies -q -O - \"%s%s\"";
	FILE *fjobs = read_cmd_output(cmd, http_baseurl, http_apipath);
	pclose(fjobs);
}

void addceinfo(int solution_id)
{
	if (http_judge)
	{
		_addceinfo_http(solution_id);
	}
	else
	{

#ifdef _mysql_h
		_addceinfo_mysql(solution_id);
#endif
	}
}

/* write runtime error message back to database */
#ifdef _mysql_h
void _addreinfo_mysql(int solution_id, const char *filename)
{
	char sql[(1 << 16)], *end;
	char reinfo[(1 << 16)], *rend;
	FILE *fp = fopen(filename, "re");
	snprintf(sql, (1 << 16) - 1, "DELETE FROM runtimeinfo WHERE solution_id=%d",
			 solution_id);
	mysql_real_query(conn, sql, strlen(sql));
	rend = reinfo;
	while (fgets(rend, 1024, fp))
	{
		rend += strlen(rend);
		if (rend - reinfo > 16384)
			break;
	}
	*rend = '\0';
	end = sql;
	strcpy(end, "INSERT INTO runtimeinfo VALUES(");
	end += strlen(sql);
	*end++ = '\'';
	end += sprintf(end, "%d", solution_id);
	*end++ = '\'';
	*end++ = ',';
	*end++ = '\'';
	end += mysql_real_escape_string(conn, end, reinfo, strlen(reinfo));
	*end++ = '\'';
	*end++ = ')';
	*end = 0;
	//      printf("%s\n",ceinfo);
	if (mysql_real_query(conn, sql, end - sql))
		printf("%s\n", mysql_error(conn));
	fclose(fp);
}
#endif

void _addreinfo_http(int solution_id, const char *filename)
{

	char reinfo[(1 << 16)], *rend;
	char *reinfo_encode;
	FILE *fp = fopen(filename, "re");

	rend = reinfo;
	while (fgets(rend, 1024, fp))
	{
		rend += strlen(rend);
		if (rend - reinfo > 16384)
			break;
	}
	*rend = '\0';
	fclose(fp);
	reinfo_encode = url_encode(reinfo);
	FILE *re = fopen("re.post", "we");
	fprintf(re, "addreinfo=1&sid=%d&reinfo=%s", solution_id, reinfo_encode);
	fclose(re);
	free(reinfo_encode);

	const char *cmd =
		" wget --post-file=\"re.post\" --load-cookies=cookie --save-cookies=cookie --keep-session-cookies -q -O - \"%s%s\"";
	FILE *fjobs = read_cmd_output(cmd, http_baseurl, http_apipath);
	// fscanf(fjobs,"%d",&ret);
	pclose(fjobs);
}

void addreinfo(int solution_id)
{
	if (http_judge)
	{
		_addreinfo_http(solution_id, "error.out");
	}
	else
	{
#ifdef _mysql_h
		_addreinfo_mysql(solution_id, "error.out");
#endif
	}
}

void adddiffinfo(int solution_id)
{

	if (http_judge)
	{
		_addreinfo_http(solution_id, "diff.out");
	}
	else
	{
#ifdef _mysql_h
		_addreinfo_mysql(solution_id, "diff.out");
#endif
	}
}

void addcustomout(int solution_id)
{

	if (http_judge)
	{
		_addreinfo_http(solution_id, "user.out");
	}
	else
	{
#ifdef _mysql_h
		_addreinfo_mysql(solution_id, "user.out");
#endif
	}
}

#ifdef _mysql_h
void _update_user_mysql(char *user_id)
{
	char sql[BUFFER_SIZE];
	sprintf(sql,
			"UPDATE `users` SET `solved`=(SELECT count(DISTINCT `problem_id`) FROM `solution` WHERE `user_id`=\'%s\' AND `result`=4) WHERE `user_id`=\'%s\'",
			user_id, user_id);
	if (mysql_real_query(conn, sql, strlen(sql)))
		write_log(mysql_error(conn));
	sprintf(sql,
			"UPDATE `users` SET `submit`=(SELECT count(*) FROM `solution` WHERE `user_id`=\'%s\' and problem_id>0) WHERE `user_id`=\'%s\'",
			user_id, user_id);
	if (mysql_real_query(conn, sql, strlen(sql)))
		write_log(mysql_error(conn));
}
#endif

void _update_user_http(char *user_id)
{

	const char *cmd =
		" wget --post-data=\"updateuser=1&user_id=%s\" --load-cookies=cookie --save-cookies=cookie --keep-session-cookies -q -O - \"%s%s\"";
	FILE *fjobs = read_cmd_output(cmd, user_id, http_baseurl, http_apipath);
	// fscanf(fjobs,"%d",&ret);
	pclose(fjobs);
}

void update_user(char *user_id)
{
	if (http_judge)
	{
		_update_user_http(user_id);
	}
	else
	{

#ifdef _mysql_h
		_update_user_mysql(user_id);
#endif
	}
}

void _update_problem_http(int pid, int cid)
{
	const char *cmd =
		" wget --post-data=\"updateproblem=1&pid=%d\" --load-cookies=cookie --save-cookies=cookie --keep-session-cookies -q -O - \"%s%s\"";
	FILE *fjobs = read_cmd_output(cmd, pid, http_baseurl, http_apipath);
	// fscanf(fjobs,"%d",&ret);
	pclose(fjobs);
}

#ifdef _mysql_h
void _update_problem_mysql(int p_id, int cid)
{
	char sql[BUFFER_SIZE];

	sprintf(sql,
			"UPDATE `problem` SET `accepted`=(SELECT count(*) FROM `solution` WHERE `problem_id`=%d AND `result`=4) WHERE `problem_id`=%d",
			p_id, p_id);
	printf("sql:[%s]\n", sql);

	if (mysql_real_query(conn, sql, strlen(sql)))
		write_log(mysql_error(conn));
}
#endif

void update_problem(int pid, int cid)
{
	if (http_judge)
	{
		_update_problem_http(pid, cid);
	}
	else
	{
#ifdef _mysql_h
		_update_problem_mysql(pid, cid);
#endif
	}
}

void umount(char *work_dir) 
{
	if (chdir(work_dir))
		exit(-1);
	execute_cmd("/bin/umount -l %s/usr 2>/dev/null", work_dir);
	if (strlen(work_dir) > 0)
	{
		execute_cmd("/bin/umount -l %s/proc 2>/dev/null", work_dir);
	}
	execute_cmd("/bin/umount -l %s/dev 2>/dev/null", work_dir);
	execute_cmd("/bin/umount -l %s/usr 2>/dev/null", work_dir);
	execute_cmd("/bin/umount -l usr dev");
	execute_cmd("/bin/umount -l lib lib64");
	execute_cmd("/bin/rmdir %s/* ", work_dir);
	execute_cmd("/bin/rmdir %s/log/* ", work_dir);
}

int compile(int lang, char *work_dir, int leetcode, char *src_pth)
{
	printf("\ncompiling, language:%d\n",lang);
	if (lang == LANG_PYTHON || lang == LANG_JS)
		return 0; 
	int pid;
	char fmax_errors[BUFFER_SIZE];

	if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8))
	{
		sprintf(fmax_errors, "-fmax-errors=10");
	}
	else
	{
		sprintf(fmax_errors, "-Wformat");
	}
	const char *CP_C[] = {"gcc", "-fno-asm", cc_opt, fmax_errors, cc_std,
						  "-Wall", "--static", "-DONLINE_JUDGE", "-o", "Main", "Main.c", "-lm", NULL}; 
	if (leetcode == 1)
	{
		strcpy(cpp_std, "-std=c++17");
	}
	const char *CP_X[] = {"g++", "-fno-asm", cc_opt, fmax_errors, cpp_std,
						  "-Wall", "-lm", "--static", "-DONLINE_JUDGE", "-o", "Main", "Main.cc", NULL};
	printf("\ncc_opt:%s, fmax_errors:%s, cpp_std:%s\n",cc_opt, fmax_errors, cpp_std);
	const char *CP_P[] =
		{"fpc", "Main.pas", "-Cs32000000", "-Sh", "-O2", "-Co", "-Ct", "-Ci", NULL};

	const char *CP_R[] = {"ruby", "-c", "Main.rb", NULL};
	const char *CP_B[] = {"chmod", "+rx", "Main.sh", NULL};
	const char *CP_Y[] = {"python3", "-c",
						  "import py_compile; py_compile.compile(r'Main.py')", NULL};
	const char *CP_PH[] = {"php", "-l", "Main.php", NULL};
	const char *CP_PL[] = {"perl", "-c", "Main.pl", NULL};
	const char *CP_CS[] = {"mcs", "-codepage:utf8", "-warn:0", "Main.cs", NULL};
	const char *CP_OC[] = {"gcc", "-o", "Main", "Main.m",
						   "-fconstant-string-class=NSConstantString", "-I",
						   "/usr/include/GNUstep/", "-L", "/usr/lib/GNUstep/Libraries/",
						   "-lobjc", "-lgnustep-base", NULL};
	const char *CP_BS[] = {"fbc", "-lang", "qb", "Main.bas", NULL};
	const char *CP_CLANG[] = {"clang", "Main.c", "-o", "Main", "-ferror-limit=10", "-fno-asm", "-Wall",
							  "-lm", "--static", "-std=c99", "-DONLINE_JUDGE", NULL};
	const char *CP_CLANG_CPP[] = {"clang++", "Main.cc", "-o", "Main", "-ferror-limit=10", "-fno-asm", "-Wall",
								  "-lm", "--static", "-std=c++0x", "-DONLINE_JUDGE", NULL};
	const char *CP_LUA[] = {"luac", "-o", "Main", "Main.lua", NULL};
	const char *CP_GO[] = {"go", "build", "-o", "Main", "Main.go", NULL};
	const char *CP_FORTRAN[] = {"f95", "-static", "-o", "Main", "Main.f95", NULL};
	const char *CP_COBOL[] = {"cobc", "-x", "-static", "-o", "Main", "Main.cob", NULL};

	char *const envp[] = {(char *const)"PYTHONIOENCODING=utf-8",
						  (char *const)"USER=judge",
						  (char *const)"GOCACHE=/tmp",
						  (char *const)"LANG=zh_CN.UTF-8",
						  (char *const)"LANGUAGE=zh_CN.UTF-8",
						  (char *const)"LC_ALL=zh_CN.utf-8", NULL};


	char javac_buf[7][32];
	char *CP_J[7];
	for (int i = 0; i < 7; i++)
		CP_J[i] = javac_buf[i];
	sprintf(CP_J[0], "javac");
	sprintf(CP_J[1], "-J%s", java_xms);
	sprintf(CP_J[2], "-J%s", java_xmx);
	sprintf(CP_J[3], "-encoding");
	sprintf(CP_J[4], "UTF-8");
	sprintf(CP_J[5], "%s",src_pth);
	CP_J[6] = (char *)NULL;
	
	pid = fork();


	if (pid == 0)
	{
		struct rlimit LIM;
		int cpu = 50;
		if (lang == 3)
			cpu = 60;
		LIM.rlim_max = cpu;
		LIM.rlim_cur = cpu;
		LIM.rlim_max = 500 * STD_MB;
		LIM.rlim_cur = 500 * STD_MB;

		if (lang == 2 || lang == 3 || lang == 17)
		{
#ifdef __mips__
			LIM.rlim_max = STD_MB << 12;
			LIM.rlim_cur = STD_MB << 12;
#endif
#ifdef __arm__
			LIM.rlim_max = STD_MB << 11;
			LIM.rlim_cur = STD_MB << 11;
#endif
#ifdef __i386__
			LIM.rlim_max = STD_MB << 11;
			LIM.rlim_cur = STD_MB << 11;
#endif
#ifdef __x86_64__
			LIM.rlim_max = STD_MB << 12;
			LIM.rlim_cur = STD_MB << 12;
#endif
		}
		else
		{
			LIM.rlim_max = STD_MB << 11;
			LIM.rlim_cur = STD_MB << 11;
		}

		printf("redirecting to ce file");
		if (lang != 2 && lang != 11)
		{
			stderr = freopen("ce.txt", "w", stderr);
		}
		else
		{
			stdout = freopen("ce.txt", "w", stdout);
		}

		printf("\nafter redirecting\n");


		printf("\nafter chown\n");
		if (compile_chroot && lang != 3 && lang != 9 && lang != 6 && lang != 11 && lang != 5)
		{
			if (access("usr", F_OK) == -1)
			{
				execute_cmd("mkdir -p root/.cache/go-build usr etc/alternatives proc tmp dev");
				execute_cmd("chown judge -R root tmp ");
				execute_cmd("mount -o bind /usr usr");
				execute_cmd("mount -o remount,ro usr");
				execute_cmd("ln -s usr/bin bin");
				execute_cmd("ln -s usr/lib lib");
				execute_cmd("ln -s usr/lib32 lib32");
				execute_cmd("ln -s usr/libx32 libx32");
#ifndef __i386__
				execute_cmd("ln -s usr/lib64 lib64");
#endif
				execute_cmd("cp /etc/alternatives/* etc/alternatives");
				execute_cmd("cp /etc/fpc* etc/");
				execute_cmd("mount -o bind /proc proc");
				if (lang > 2 && lang != 6 && lang != 10 && lang != 13 && lang != 14)
				{
					execute_cmd("mount -o bind /dev dev");
					execute_cmd("mount -o remount,ro dev");
				}
			}
			if (chroot(work_dir))
				printf("warning chroot fail!\n");
		}
		printf("\nafter chrooting\n");
		while (setgid(1536) != 0)
			sleep(1);
		while (setuid(1536) != 0)
			sleep(1);
		while (setresuid(1536, 1536, 1536) != 0)
			sleep(1);
		
		printf("lang before switch:%d",lang);
		switch (lang)
		{
		case LANG_C:
			execvp(CP_C[0], (char *const *)CP_C);
			break;
		case LANG_CPP:
			execvp(CP_X[0], (char *const *)CP_X);
			break;
		case LANG_PASCAL:
			execvp(CP_P[0], (char *const *)CP_P);
			break;
		case LANG_JAVA:
			{
				printf("JAVA DEBUG");
				if(leetcode==1){
					printf("compiling leetcode");
					std::string work_dir_str(work_dir);
					std::string command = "bash /home/judge/leetcode_template/java/compile.sh " + work_dir_str;
					const char *command_cstr = command.c_str();
					printf("\n%s\n", command_cstr);
					int result = system(command_cstr);
					if (result == 0)
					{
						printf("Shell script executed successfully.\n");
					}
					else
					{
						printf("Failed to execute shell script.\n");
					}

				}
				else{
					execvp(CP_J[0], (char *const *)CP_J);
				}
			
			}
			break;
		case LANG_RUBY:
			execvp(CP_R[0], (char *const *)CP_R);
			break;
		case LANG_BASH:
			execvp(CP_B[0], (char *const *)CP_B);
			break;
		case LANG_PYTHON:
			execvp(CP_Y[0], (char *const *)CP_Y);
			break;
		case LANG_PHP:
			execvp(CP_PH[0], (char *const *)CP_PH);
			break;
		case LANG_PERL:
			execvp(CP_PL[0], (char *const *)CP_PL);
			break;
		case LANG_CSHARP:
			execvp(CP_CS[0], (char *const *)CP_CS);
			break;
		case LANG_OBJC:
			execvp(CP_OC[0], (char *const *)CP_OC);
			break;
		case LANG_FREEBASIC:
			execvp(CP_BS[0], (char *const *)CP_BS);
			break;
		case LANG_CLANG:
			execvp(CP_CLANG[0], (char *const *)CP_CLANG);
			break;
		case LANG_CLANGPP:
			execvp(CP_CLANG_CPP[0], (char *const *)CP_CLANG_CPP);
			break;
		case LANG_LUA:
			execvp(CP_LUA[0], (char *const *)CP_LUA);
			break;
		case LANG_GO:
			execvpe(CP_GO[0], (char *const *)CP_GO, envp);
			break;
		case LANG_FORTRAN:
			execvp(CP_FORTRAN[0], (char *const *)CP_FORTRAN);
			break;
		case LANG_COBOL:
			execvp(CP_COBOL[0], (char *const *)CP_COBOL);
			break;
		default:
			if (DEBUG)
				write_log("nothing to do!\n");
		}
		exit(0);
	}
	else
	{
		int status = 0;

		waitpid(pid, &status, 0);
		if (lang > 3 && lang < 7)
			status = get_file_size("ce.txt");
		if (DEBUG)
			printf("status=%d\n", status);
		execute_cmd("/bin/umount -l bin usr lib lib64 etc/alternatives dev 2>/dev/null");
		umount(work_dir);

		return status;
	}
}

int get_proc_status(int pid, const char *mark)
{
	FILE *pf;
	char fn[BUFFER_SIZE], buf[BUFFER_SIZE];
	int ret = 0;
	sprintf(fn, "/proc/%d/status", pid);
	pf = fopen(fn, "re");
	int m = strlen(mark);
	while (pf && fgets(buf, BUFFER_SIZE - 1, pf))
	{

		buf[strlen(buf) - 1] = 0;
		if (strncmp(buf, mark, m) == 0)
		{
			if (1 != sscanf(buf + m + 1, "%d", &ret))
				printf("proc read fail\n");
		}
	}
	if (pf)
		fclose(pf);
	return ret;
}

#ifdef _mysql_h
int init_mysql_conn() 
{

	conn = mysql_init(NULL);
	const char timeout = 30;
	mysql_options(conn, MYSQL_OPT_CONNECT_TIMEOUT, &timeout);

	if (!mysql_real_connect(conn, host_name, user_name, password, db_name,
							port_number, 0, 0))
	{
		write_log("%s", mysql_error(conn));
		return 0;
	}
	const char *utf8sql = "set names utf8";
	if (mysql_real_query(conn, utf8sql, strlen(utf8sql)))
	{
		write_log("%s", mysql_error(conn));
		return 0;
	}
	return 1;
}

int check_mysql_conn()
{
	MYSQL_RES *res;
	const char *sql = "select 1";
	while (mysql_real_query(conn, sql, strlen(sql)))
	{
		if (DEBUG)
		{
			printf("..update failed! %s\n", mysql_error(conn));
			write_log("\n.......Mysql time out !---- retry............\n");
		}
		mysql_close(conn);
		sleep(1);
		init_mysql_conn();
	}
	res = mysql_store_result(conn);
	mysql_free_result(res);
	return 0;
}

#endif

char *replace_class_name(const char *source, const char *new_class_name)
{
	char *result;
	int count = 0;
	size_t old_len;
	size_t new_len = strlen(new_class_name);

	const char *start_ptr = strstr(source, "public class ");
	if (start_ptr == NULL)
	{
		return strdup(source); 
	}
	start_ptr += strlen("public class ");
	const char *end_ptr = strchr(start_ptr, ' ');
	if (end_ptr == NULL)
	{
		return strdup(source); 
	}
	old_len = end_ptr - start_ptr;
	result = (char *)malloc(strlen(source) + (new_len - old_len) + 1);
	if (result == NULL)
	{
		fprintf(stderr, "Memory allocation failed.\n");
		exit(EXIT_FAILURE);
	}
	strncpy(result, source, start_ptr - source);
	result[start_ptr - source] = '\0';
	strcat(result, new_class_name);
	strcat(result, end_ptr);

	return result;
}

const char* findNearestDelimiter(const char* start_ptr) {
    const char delimiters[] = " \n\t{";
    const char* delimiter_ptr = std::strpbrk(start_ptr, delimiters);

    if (delimiter_ptr == nullptr) {
        return nullptr; 
    } else {
        return delimiter_ptr; 
    }
}


char *get_class_name(const char *source)
{
	const char *start_ptr = strstr(source, "public");
	bool flag = false;
	if (start_ptr==NULL) {
		return NULL;
	}
	while ((start_ptr = strstr(start_ptr, "public")) != NULL) {
		start_ptr += strlen("public");
		while (isspace(*start_ptr)) {
			start_ptr++;
		}
		if (strncmp(start_ptr, "final", 5) == 0){
			start_ptr = strstr(start_ptr, "final");
			start_ptr += strlen("final");
			while (isspace(*start_ptr)) {
				start_ptr++;
			}
		}
		if (strncmp(start_ptr, "class", 5) == 0){
			const char *class_ptr = strstr(start_ptr, "class");
			if (class_ptr == NULL) {
				flag = false; 
				continue;
			} else{
				start_ptr = class_ptr;
				start_ptr += strlen("class");
				if (*start_ptr != ' ') {
					flag = false; 
					continue;
				}
				start_ptr++; 
				flag = true;
				break;
			}
		}
	}
    if (!flag){
		return NULL;
	}
	
    while (*start_ptr && strchr(" \t", *start_ptr)) {
        start_ptr++;
    }

	const char* end_ptr = findNearestDelimiter(start_ptr);
    if (end_ptr == NULL) {
        return NULL; 
    }

    size_t old_len = end_ptr - start_ptr;
    char *class_name = (char *)malloc(old_len + 1);
    if (class_name == NULL) {
        fprintf(stderr, "Memory allocation failed.\n");
        exit(EXIT_FAILURE);
    }

    strncpy(class_name, start_ptr, old_len);
    class_name[old_len] = '\0';

    return class_name;
}

#ifdef _mysql_h
void _get_solution_mysql(int solution_id, char *work_dir, int lang, char *src_pth )
{
	char sql[BUFFER_SIZE];
	FILE *fp_src;
	MYSQL_RES *res;
	MYSQL_ROW row;
	sprintf(sql, "SELECT source FROM source_code WHERE solution_id=%d",
			solution_id);
	mysql_real_query(conn, sql, strlen(sql));
	res = mysql_store_result(conn);
	if (res != NULL)
	{
		row = mysql_fetch_row(res);
		if (row != NULL)
		{

			if (lang==3)
			{
				
				char *public_name  = get_class_name(row[0]);
				if (public_name==NULL){
					public_name="Main";
				}
				sprintf(src_pth, "%s.java",public_name);
				if (DEBUG)
					printf("Main(srcpth)=%s", src_pth);
				fp_src = fopen(src_pth, "we");
				fprintf(fp_src, "%s", row[0]);

			}
			else
			{
				sprintf(src_pth, "Main.%s", lang_ext[lang]);
				if (DEBUG)
					printf("Main=%s", src_pth);
				fp_src = fopen(src_pth, "we");
				fprintf(fp_src, "%s", row[0]);
			}

			mysql_free_result(res); 
			res = NULL;
			row = NULL;
			fclose(fp_src);
		}
	}
}
#endif
void _get_solution_http(int solution_id, char *work_dir, int lang, char *src_pth)
{
	sprintf(src_pth, "Main.%s", lang_ext[lang]);
	if (DEBUG)
		printf("Main=%s", src_pth);
	const char *cmd2 =
		"wget --post-data=\"getsolution=1&sid=%d\" --load-cookies=cookie --save-cookies=cookie --keep-session-cookies -q -O %s \"%s%s\"";
	FILE *pout = read_cmd_output(cmd2, solution_id, src_pth, http_baseurl, http_apipath);

	pclose(pout);
}
void get_solution(int solution_id, char *work_dir, int lang,char *src_pth)
{
	sprintf(src_pth, "Main.%s", lang_ext[lang]);
	if (http_judge)
	{
		_get_solution_http(solution_id, work_dir, lang, src_pth);
	}
	else
	{

#ifdef _mysql_h
		_get_solution_mysql(solution_id, work_dir, lang, src_pth);
#endif
	}
	if (lang == LANG_PYTHON)
	{ 
		py2 = execute_cmd("/bin/grep 'python2' %s/Main.py > /dev/null", work_dir);
		execute_cmd("sed -i 's/import.*os//g' %s/%s", work_dir, src_pth);
	}
	execute_cmd("chown judge %s/%s", work_dir, src_pth);
	execute_cmd("chown -R judge %s ", work_dir);
	execute_cmd("chmod -R 755 %s ", work_dir);
}

#ifdef _mysql_h
void _get_custominput_mysql(int solution_id, char *work_dir)
{
	char sql[BUFFER_SIZE], src_pth[BUFFER_SIZE];
	printf("geting custom input\n");
	MYSQL_RES *res;
	MYSQL_ROW row;
	sprintf(sql, "SELECT input_text FROM custominput WHERE solution_id=%d",
			solution_id);
	mysql_real_query(conn, sql, strlen(sql));
	res = mysql_store_result(conn);
	row = mysql_fetch_row(res);
	if (row != NULL)
	{
		sprintf(src_pth, "data.in");
		FILE *fp_src = fopen(src_pth, "w");
		fprintf(fp_src, "%s", row[0]);
		fclose(fp_src);
		sprintf(sql, "DELETE FROM custominput WHERE solution_id=%d", solution_id);
		mysql_real_query(conn, sql, strlen(sql));
	}
	if (res != NULL)
	{
		printf("no custom input\n");
		mysql_free_result(res);
		res = NULL;
	}
}
#endif

void _get_custominput_http(int solution_id, char *work_dir)
{
	char src_pth[BUFFER_SIZE];
	sprintf(src_pth, "data.in");
	const char *cmd2 =
		"wget --post-data=\"getcustominput=1&sid=%d\" --load-cookies=cookie --save-cookies=cookie --keep-session-cookies -q -O %s \"%s%s\"";
	FILE *pout = read_cmd_output(cmd2, solution_id, src_pth, http_baseurl, http_apipath);

	pclose(pout);
}

void get_custominput(int solution_id, char *work_dir)
{
	if (http_judge)
	{
		_get_custominput_http(solution_id, work_dir);
	}
	else
	{
#ifdef _mysql_h
		_get_custominput_mysql(solution_id, work_dir);
#endif
	}
}

#ifdef _mysql_h
void _get_solution_info_mysql(int solution_id, int &p_id, char *model_id,
							  int &lang, int &cid)
{

	MYSQL_RES *res;
	MYSQL_ROW row;

	char sql[BUFFER_SIZE];
	if (turbo_mode == 2)
	{
		sprintf(sql,
				"insert into solution2 select *  FROM solution where solution_id=%d",
				solution_id);
		mysql_real_query(conn, sql, strlen(sql));
		sprintf(sql,
				"SELECT problem_id, model_id, language,contest_id FROM solution2 where solution_id=%d",
				solution_id);
	}
	else
	{
		sprintf(sql,
				"SELECT problem_id, model_id, language,contest_id FROM solution where solution_id=%d",
				solution_id);
	}
	mysql_real_query(conn, sql, strlen(sql));
	res = mysql_store_result(conn);
	row = mysql_fetch_row(res);
	p_id = atoi(row[0]);
	strcpy(model_id, row[1]);

	lang = atoi(row[2]);
	if (row[3] == NULL)
		cid = 0;
	else
		cid = atoi(row[3]);
	printf("model_id:%s\n", model_id);
	printf("model_cid:%d\n", cid);
	if (res != NULL)
	{
		mysql_free_result(res); 
		res = NULL;
	}
}
#endif

void _get_solution_info_http(int solution_id, int &p_id, char *model_id,
							 int &lang, int &cid)
{

	login();

	const char *cmd =
		"wget --post-data=\"getsolutioninfo=1&sid=%d\" --load-cookies=cookie --save-cookies=cookie --keep-session-cookies -q -O - \"%s%s\"";
	FILE *pout = read_cmd_output(cmd, solution_id, http_baseurl, http_apipath);
	if (1 != fscanf(pout, "%d", &p_id))
		printf("http problem_id read fail...\n");
	if (1 != fscanf(pout, "%s", model_id))
		printf("http model_id read fail ... \n");
	if (1 != fscanf(pout, "%d", &lang))
		printf("http language read fail ... \n");
	if (1 != fscanf(pout, "%d", &cid))
		printf("http contest_id read fail ... \n");
	pclose(pout);
}

void get_solution_info(int solution_id, int &p_id, char *model_id,
					   int &lang, int &cid)
{

	if (http_judge)
	{
		_get_solution_info_http(solution_id, p_id, model_id, lang, cid);
	}
	else
	{
#ifdef _mysql_h
		_get_solution_info_mysql(solution_id, p_id, model_id, lang, cid);
#endif
	}
}

#ifdef _mysql_h
void _get_problem_info_mysql(int p_id, double &time_lmt, int &mem_lmt,
							 int &spj, int &leetcode)
{
	char sql[BUFFER_SIZE];
	MYSQL_RES *res;
	MYSQL_ROW row;
	sprintf(sql,
			"SELECT time_limit,memory_limit,spj,leetcode FROM problem where problem_id=%d",
			p_id);
	mysql_real_query(conn, sql, strlen(sql));
	res = mysql_store_result(conn);
	row = mysql_fetch_row(res);
	time_lmt = atof(row[0]);
	mem_lmt = atoi(row[1]);
	spj = atoi(row[2]);
	if (strcmp(row[3], "Y") == 0)
	{
		leetcode = 1;
	}
	else
	{
		leetcode = 0;
	}

	if (res != NULL)
	{
		mysql_free_result(res); 
		res = NULL;
	}
}
#endif

void _get_problem_info_http(int p_id, double &time_lmt, int &mem_lmt,
							int &spj)
{
	const char *cmd =
		"wget --post-data=\"getprobleminfo=1&pid=%d\" --load-cookies=cookie --save-cookies=cookie --keep-session-cookies -q -O - \"%s%s\"";
	FILE *pout = read_cmd_output(cmd, p_id, http_baseurl, http_apipath);
	if (1 != fscanf(pout, "%lf", &time_lmt))
		printf("http read time_limit fail...\n");
	if (1 != fscanf(pout, "%d", &mem_lmt))
		printf("http read memory_limit fail...\n");
	if (1 != fscanf(pout, "%d", &spj))
		printf("http read special judge fail...\n");
	pclose(pout);
	if (DEBUG)
		printf("time_lmt:%g\n", time_lmt);
}

void get_problem_info(int p_id, double &time_lmt, int &mem_lmt, int &spj, int &leetcode)
{
	if (http_judge)
	{
		_get_problem_info_http(p_id, time_lmt, mem_lmt, spj);
	}
	else
	{
#ifdef _mysql_h
		_get_problem_info_mysql(p_id, time_lmt, mem_lmt, spj, leetcode);
#endif
	}
	if (time_lmt <= 0)
		time_lmt = 1;
}

char *escape(char s[], char t[])
{
	int i, j;
	for (i = j = 0; t[i] != '\0'; ++i)
	{
		if (t[i] == '\'')
		{
			s[j++] = '\'';
			s[j++] = '\\';
			s[j++] = '\'';
			s[j++] = '\'';
			continue;
		}
		else
		{
			s[j++] = t[i];
		}
	}
	s[j] = '\0';
	return s;
}

void prepare_files(char *filename, int namelen, char *infile, int &p_id,
				   char *work_dir, char *outfile, char *userfile, int runner_id)
{
	char fname0[BUFFER_SIZE];
	char fname[BUFFER_SIZE];
	strncpy(fname0, filename, namelen);
	fname0[namelen] = 0;
	escape(fname, fname0);
	sprintf(infile, "%s/data/%d/%s.in", oj_home, p_id, fname);
	char noip_file_name[BUFFER_SIZE];
	sprintf(noip_file_name, "%s/data/%d/input.name", oj_home, p_id);
	if (DEBUG)
		printf("NOIP filename:%s\n", noip_file_name);
	if (access(noip_file_name, R_OK) != -1)
	{
		if (DEBUG)
			printf("NOIP filename:%s\n", noip_file_name);
		FILE *fpname = fopen(noip_file_name, "r");
		if (fscanf(fpname, "%s", noip_file_name))
		{
			execute_cmd("/bin/cp '%s' %s/%s", infile, work_dir, basename(noip_file_name)); 
			execute_cmd("/usr/bin/chown judge %s/%s", work_dir, basename(noip_file_name)); 
			if (DEBUG)
				printf("NOIP filename:%s\n", noip_file_name);
		}
		fclose(fpname);
	}
	else
	{
		if (copy_data)
			execute_cmd("/bin/cp '%s' %s/data.in", infile, work_dir); 
	}
	execute_cmd("/bin/cp %s/data/%d/*.dic %s/ 2>/dev/null", oj_home, p_id, work_dir);
	execute_cmd("chown judge %s/*.dic ", work_dir);
	sprintf(outfile, "%s/data/%d/%s.out", oj_home, p_id, fname0);
	printf("outfile:%s\n",outfile);
	sprintf(noip_file_name, "%s/data/%d/output.name", oj_home, p_id);
	if (DEBUG)
		printf("NOIP filename:%s\n", noip_file_name);
	if (access(noip_file_name, R_OK) != -1)
	{
		FILE *fpname = fopen(noip_file_name, "r");
		if (fscanf(fpname, "%s", noip_file_name))
		{
			if (DEBUG)
				printf("NOIP filename:%s\n", noip_file_name);
			if (!strstr("noip_file_name", "//"))
			{
				sprintf(userfile, "%s/run%d/%s", oj_home, runner_id, basename(noip_file_name));
				execute_cmd("rm %s", userfile);
			}
		}
		fclose(fpname);
	}
	else
	{
		sprintf(userfile, "%s/run%d/user.out", oj_home, runner_id);
		execute_cmd("rm %s", userfile);
	}
}

void copy_shell_runtime(char *work_dir)
{

	execute_cmd("/bin/mkdir %s/lib", work_dir);
	execute_cmd("/bin/mkdir %s/lib64", work_dir);
	execute_cmd("/bin/mkdir %s/bin", work_dir);
#ifdef __mips__
	execute_cmd("/bin/cp -a /lib/mips64el-linux-gnuabi64/  %s/lib/mips64el-linux-gnuabi64", work_dir);
	execute_cmd("mkdir -p %s/lib/mips64el-linux-gnuabi64/", work_dir);
	execute_cmd("/bin/cp -a /lib64/ld.so.1  %s/lib64/", work_dir);
	execute_cmd("/bin/cp -a /lib/mips64el-linux-gnuabi64/libdl.so.2  %s/lib/mips64el-linux-gnuabi64", work_dir);
	execute_cmd("/bin/cp -a /lib/mips64el-linux-gnuabi64/libutil.so.1  %s/lib/mips64el-linux-gnuabi64", work_dir);
	execute_cmd("/bin/cp -a /lib/mips64el-linux-gnuabi64/libz.so.1  %s/lib/mips64el-linux-gnuabi64", work_dir);
	execute_cmd("/bin/cp -a /lib/mips64el-linux-gnuabi64/libm.so.6  %s/lib/mips64el-linux-gnuabi64", work_dir);
	execute_cmd("/bin/cp -a /lib/mips64el-linux-gnuabi64/libc.so.6  %s/lib/mips64el-linux-gnuabi64", work_dir);
	execute_cmd("/bin/cp -a /lib/mips64el-linux-gnuabi64/libtinfo.so.5  %s/lib/mips64el-linux-gnuabi64", work_dir);
	execute_cmd("/bin/cp -a /lib/mips64el-linux-gnuabi64/ld-2.24.so  %s/lib/mips64el-linux-gnuabi64", work_dir);
	execute_cmd("/bin/cp -a /lib/mips64el-linux-gnuabi64/libc-2.24.so  %s/lib/mips64el-linux-gnuabi64", work_dir);
	execute_cmd("/bin/cp -a /lib64/libc.so.6 %s/lib64/", work_dir);
	execute_cmd("/bin/cp -a /lib64/libtinfo.so.6  %s/lib64/", work_dir);
	execute_cmd("/bin/cp -a /lib64/ld-2.27.so  %s/lib64/", work_dir);
	execute_cmd("/bin/cp -a /lib64/libc-2.27.so %s/lib64/", work_dir);
	execute_cmd("/bin/cp -a /lib64/libdl-2.27.so %s/lib64/", work_dir);
	execute_cmd("/bin/cp -a /lib64/libtinfo.so.6.1 %s/lib64/", work_dir);
	execute_cmd("cp  /lib/mips64el-linux-gnuabi64/libpthread.so.0 %s/lib/mips64el-linux-gnuabi64/", work_dir);
	execute_cmd("/bin/cp -a /bin/bash %s/bin/", work_dir);

#endif

#ifdef __i386
	execute_cmd("/bin/cp /lib/ld-linux* %s/lib/", work_dir);
	execute_cmd("/bin/cp -a /lib/i386-linux-gnu/  %s/lib/", work_dir);
#endif

#ifdef __x86_64__
	execute_cmd("mount -o bind /lib %s/lib", work_dir);
	execute_cmd("mount -o bind /lib64 %s/lib64", work_dir);
#endif
	execute_cmd("/bin/cp /bin/busybox %s/bin/", work_dir);
	execute_cmd("/bin/ln -s /bin/busybox %s/bin/sh", work_dir);
	execute_cmd("/bin/cp /bin/bash %s/bin/bash", work_dir);
}

void copy_objc_runtime(char *work_dir)
{
	copy_shell_runtime(work_dir);
	execute_cmd("/bin/mkdir -p %s/proc", work_dir);
	execute_cmd("/bin/mount -o bind /proc %s/proc", work_dir);
	execute_cmd("/bin/mkdir -p %s/lib/", work_dir);
	execute_cmd(
		"/bin/cp -aL /lib/libdbus-1.so.3                          %s/lib/ ",
		work_dir);
	execute_cmd(
		"/bin/cp -aL /lib/libgcc_s.so.1                           %s/lib/ ",
		work_dir);
	execute_cmd(
		"/bin/cp -aL /lib/libgcrypt.so.11                         %s/lib/ ",
		work_dir);
	execute_cmd(
		"/bin/cp -aL /lib/libgpg-error.so.0                       %s/lib/ ",
		work_dir);
	execute_cmd(
		"/bin/cp -aL /lib/libz.so.1                               %s/lib/ ",
		work_dir);
	execute_cmd(
		"/bin/cp -aL /lib/tls/i686/cmov/libc.so.6                 %s/lib/ ",
		work_dir);
	execute_cmd(
		"/bin/cp -aL /lib/tls/i686/cmov/libdl.so.2                %s/lib/ ",
		work_dir);
	execute_cmd(
		"/bin/cp -aL /lib/tls/i686/cmov/libm.so.6                 %s/lib/ ",
		work_dir);
	execute_cmd(
		"/bin/cp -aL /lib/tls/i686/cmov/libnsl.so.1               %s/lib/ ",
		work_dir);
	execute_cmd(
		"/bin/cp -aL /lib/tls/i686/cmov/libpthread.so.0           %s/lib/ ",
		work_dir);
	execute_cmd(
		"/bin/cp -aL /lib/tls/i686/cmov/librt.so.1                %s/lib/ ",
		work_dir);
	execute_cmd(
		"/bin/cp -aL /usr/lib/libavahi-client.so.3                %s/lib/ ",
		work_dir);
	execute_cmd(
		"/bin/cp -aL /usr/lib/libavahi-common.so.3                %s/lib/ ",
		work_dir);
	execute_cmd(
		"/bin/cp -aL /usr/lib/libdns_sd.so.1                      %s/lib/ ",
		work_dir);
	execute_cmd(
		"/bin/cp -aL /usr/lib/libffi.so.5                         %s/lib/ ",
		work_dir);
	execute_cmd(
		"/bin/cp -aL /usr/lib/libgnustep-base.so.1.19             %s/lib/ ",
		work_dir);
	execute_cmd(
		"/bin/cp -aL /usr/lib/libgnutls.so.26                     %s/lib/ ",
		work_dir);
	execute_cmd(
		"/bin/cp -aL /usr/lib/libobjc.so.2                        %s/lib/ ",
		work_dir);
	execute_cmd(
		"/bin/cp -aL /usr/lib/libtasn1.so.3                       %s/lib/ ",
		work_dir);
	execute_cmd(
		"/bin/cp -aL /usr/lib/libxml2.so.2                        %s/lib/ ",
		work_dir);
	execute_cmd(
		"/bin/cp -aL /usr/lib/libxslt.so.1                        %s/lib/ ",
		work_dir);
}

void copy_bash_runtime(char *work_dir)
{
	copy_shell_runtime(work_dir);
	execute_cmd("/bin/cp `which bc`  %s/bin/", work_dir);
	execute_cmd("busybox dos2unix Main.sh", work_dir);
	execute_cmd("/bin/ln -s /bin/busybox %s/bin/grep", work_dir);
	execute_cmd("/bin/ln -s /bin/busybox %s/bin/awk", work_dir);
	execute_cmd("/bin/cp /bin/sed %s/bin/sed", work_dir);
	execute_cmd("/bin/ln -s /bin/busybox %s/bin/cut", work_dir);
	execute_cmd("/bin/ln -s /bin/busybox %s/bin/sort", work_dir);
	execute_cmd("/bin/ln -s /bin/busybox %s/bin/join", work_dir);
	execute_cmd("/bin/ln -s /bin/busybox %s/bin/wc", work_dir);
	execute_cmd("/bin/ln -s /bin/busybox %s/bin/tr", work_dir);
	execute_cmd("/bin/ln -s /bin/busybox %s/bin/dc", work_dir);
	execute_cmd("/bin/ln -s /bin/busybox %s/bin/dd", work_dir);
	execute_cmd("/bin/ln -s /bin/busybox %s/bin/cat", work_dir);
	execute_cmd("/bin/ln -s /bin/busybox %s/bin/tail", work_dir);
	execute_cmd("/bin/ln -s /bin/busybox %s/bin/head", work_dir);
	execute_cmd("/bin/ln -s /bin/busybox %s/bin/xargs", work_dir);
	execute_cmd("chmod +rx %s/Main.sh", work_dir);
}

void copy_ruby_runtime(char *work_dir)
{

	copy_shell_runtime(work_dir);
	execute_cmd("mkdir -p %s/usr/bin", work_dir);
	execute_cmd("mkdir -p %s/usr/lib", work_dir);
	execute_cmd("mkdir -p %s/usr/lib64", work_dir);
	execute_cmd("cp -a /usr/lib/libruby* %s/usr/lib/", work_dir);
	execute_cmd("cp -a /usr/lib/ruby* %s/usr/lib/", work_dir);
	execute_cmd("cp -a /usr/lib64/ruby* %s/usr/lib64/", work_dir);
	execute_cmd("cp -a /usr/lib64/libruby* %s/usr/lib64/", work_dir);
	execute_cmd("cp -a /usr/bin/ruby* %s/usr/bin", work_dir);
#ifdef __x86_64__
	execute_cmd("/bin/cp -a /usr/lib/x86_64-linux-gnu/libruby* %s/usr/lib/", work_dir);
	execute_cmd("/bin/cp -a /usr/lib/x86_64-linux-gnu/libgmp* %s/usr/lib/", work_dir);
#endif
}

void copy_guile_runtime(char *work_dir)
{

	copy_shell_runtime(work_dir);
	execute_cmd("/bin/mkdir -p %s/proc", work_dir);
	execute_cmd("/bin/mount -o bind /proc %s/proc", work_dir);
	execute_cmd("/bin/mkdir -p %s/usr/bin", work_dir);
	execute_cmd("/bin/mkdir -p %s/usr/lib", work_dir);
	execute_cmd("/bin/mkdir -p %s/usr/share", work_dir);
	execute_cmd("/bin/cp -a /usr/share/guile %s/usr/share/", work_dir);
	execute_cmd("/bin/cp /usr/lib/libguile* %s/usr/lib/", work_dir);
	execute_cmd("/bin/cp /usr/lib/libgc* %s/usr/lib/", work_dir);
	execute_cmd("/bin/cp /usr/lib/i386-linux-gnu/libffi* %s/usr/lib/",
				work_dir);
	execute_cmd("/bin/cp /usr/lib/i386-linux-gnu/libunistring* %s/usr/lib/",
				work_dir);
	execute_cmd("/bin/cp /usr/lib/*/libgmp* %s/usr/lib/", work_dir);
	execute_cmd("/bin/cp /usr/lib/libgmp* %s/usr/lib/", work_dir);
	execute_cmd("/bin/cp /usr/lib/*/libltdl* %s/usr/lib/", work_dir);
	execute_cmd("/bin/cp /usr/lib/libltdl* %s/usr/lib/", work_dir);
	execute_cmd("/bin/cp /usr/bin/guile* %s/usr/bin", work_dir);
#ifdef __x86_64__
	execute_cmd("/bin/cp -a /usr/lib/x86_64-linux-gnu/libguile* %s/usr/lib/", work_dir);
	execute_cmd("/bin/cp -a /usr/lib/x86_64-linux-gnu/libgc* %s/usr/lib/", work_dir);
	execute_cmd("/bin/cp -a /usr/lib/x86_64-linux-gnu/libffi* %s/usr/lib/", work_dir);
	execute_cmd("/bin/cp -a /usr/lib/x86_64-linux-gnu/libunistring* %s/usr/lib/", work_dir);
#endif
}

void copy_python_runtime(char *work_dir)
{
	copy_shell_runtime(work_dir);
	execute_cmd("mkdir -p %s/usr/include", work_dir);
	execute_cmd("mkdir -p %s/dev", work_dir);

	execute_cmd("mkdir -p %s/usr/bin", work_dir);
	execute_cmd("mkdir -p %s/usr/lib", work_dir);
	execute_cmd("mkdir -p %s/usr/lib64", work_dir);
	execute_cmd("mkdir -p %s/usr/local/lib", work_dir);
	execute_cmd("mkdir -p %s/lib/x86_64-linux-gnu", work_dir);
	execute_cmd("mkdir -p %s/etc/abrt", work_dir);
	execute_cmd("mkdir -p %s/etc/abrt/plugins", work_dir);
	execute_cmd("cp -a /etc/abrt/plugins/python.conf %s/etc/abrt/plugins/python.conf", work_dir);
	execute_cmd("mkdir -p %s/usr/share", work_dir);
	execute_cmd("mkdir -p %s/usr/share/abrt/", work_dir);
	execute_cmd("mkdir -p %s/usr/share/abrt/conf.d", work_dir);
	execute_cmd("mkdir -p %s/usr/share/abrt/conf.d/plugins", work_dir);
	execute_cmd("cp -a /usr/share/abrt/conf.d/plugins/python.conf %s/usr/share/abrt/conf.d/plugins/python.conf", work_dir);
	if (!py2)
	{
		execute_cmd("cp /usr/bin/python2* %s/usr/bin", work_dir);
		execute_cmd("cp -a /usr/lib/python2* %s/usr/lib/", work_dir);
		execute_cmd("cp -a /usr/lib64/python2.7  %s/usr/lib64/", work_dir);
#if (defined __mips__)
		execute_cmd("cp -a /usr/lib64/python2* %s/usr/lib64/", work_dir);
		execute_cmd("mkdir -p  %s/usr/local/lib/", work_dir);
		execute_cmd("cp -a /usr/local/lib/python2* %s/usr/local/lib/", work_dir);
#endif
	}
	else
	{
		execute_cmd("cp /usr/bin/python3* %s/usr/bin", work_dir);
		execute_cmd("cp -a /usr/lib/python3* %s/usr/lib/", work_dir);
		execute_cmd("cp -a /usr/lib64/python3.6  %s/usr/lib64/", work_dir);
#if (defined __mips__)
		execute_cmd("cp -a /usr/lib64/python3* %s/usr/lib64/", work_dir);
		execute_cmd("mkdir -p  %s/usr/local/lib/", work_dir);
		execute_cmd("cp -a /usr/local/lib/python3* %s/usr/local/lib/", work_dir);
#endif
	}
	execute_cmd("cp /usr/lib/lapack/* %s/usr/lib/liblapack.so.3", work_dir);
	execute_cmd("cp /usr/lib/libblas/* %s/usr/lib/libblas.so.3", work_dir);
	execute_cmd("cp /usr/lib/x86_64-linux-gnu/libgfortran.so.3 %s/usr/lib/", work_dir);
	execute_cmd("cp /usr/lib/x86_64-linux-gnu/libquadmath.so.0 %s/usr/lib", work_dir);
	execute_cmd("cp /usr/lib/x86_64-linux-gnu/blas/* %s/usr/lib", work_dir);
	execute_cmd("cp /usr/lib/x86_64-linux-gnu/liblapack.so* %s/usr/lib", work_dir);
	execute_cmd("cp /usr/lib/x86_64-linux-gnu/libgfortran.so.4 %s/usr/lib", work_dir);
#ifdef __mips__
	execute_cmd("/bin/cp -a /lib64/libpthread.so.0 %s/lib64/", work_dir);
	execute_cmd("/bin/cp -a /lib64/libutil.so.1 %s/lib64/", work_dir);
	execute_cmd("/bin/cp -a /lib64/libm.so.6 %s/lib64/", work_dir);
	execute_cmd("/bin/cp -a /lib64/libc.so.6 %s/lib64/", work_dir);
	execute_cmd("/bin/cp -a /lib64/libpthread-2.27.so %s/lib64/", work_dir);
	execute_cmd("/bin/cp -a /lib64/libutil-2.27.so %s/lib64/", work_dir);
	execute_cmd("/bin/cp -a /lib64/libc-2.27.so %s/lib64/", work_dir);
	execute_cmd("/bin/cp -a /lib64/libm-2.27.so %s/lib64/", work_dir);

#endif
	execute_cmd("cp -a /usr/lib64/libpython* %s/usr/lib64/", work_dir);
	execute_cmd("cp -a /usr/local/lib/python* %s/usr/local/lib/", work_dir);
	execute_cmd("cp -a /usr/include/python* %s/usr/include/", work_dir);
	execute_cmd("cp -a /usr/lib/libpython* %s/usr/lib/", work_dir);
	execute_cmd("/bin/mkdir -p %s/home/judge", work_dir);
	execute_cmd("/bin/chown judge %s", work_dir);
	execute_cmd("/bin/mkdir -p %s/etc", work_dir);
	execute_cmd("/bin/grep judge /etc/passwd>%s/etc/passwd", work_dir);
	execute_cmd("/bin/mount -o bind /dev %s/dev", work_dir);
	execute_cmd("/bin/mount -o remount,ro %s/dev", work_dir);
}

void copy_php_runtime(char *work_dir)
{

	copy_shell_runtime(work_dir);
	execute_cmd("/bin/mkdir -p %s/usr/bin", work_dir);
	execute_cmd("/bin/mkdir %s/usr/lib", work_dir);
	execute_cmd("/bin/cp /usr/lib/libedit* %s/usr/lib/", work_dir);
	execute_cmd("/bin/cp /usr/lib/libdb* %s/usr/lib/", work_dir);
	execute_cmd("/bin/cp /usr/lib/libgssapi_krb5* %s/usr/lib/", work_dir);
	execute_cmd("/bin/cp /usr/lib/libkrb5* %s/usr/lib/", work_dir);
	execute_cmd("/bin/cp /usr/lib/libk5crypto* %s/usr/lib/", work_dir);
	execute_cmd("/bin/cp /usr/lib/*/libedit* %s/usr/lib/", work_dir);
	execute_cmd("/bin/cp /usr/lib/*/libdb* %s/usr/lib/", work_dir);
	execute_cmd("/bin/cp /usr/lib/*/libgssapi_krb5* %s/usr/lib/", work_dir);
	execute_cmd("/bin/cp /usr/lib/*/libkrb5* %s/usr/lib/", work_dir);
	execute_cmd("/bin/cp /usr/lib/*/libk5crypto* %s/usr/lib/", work_dir);
	execute_cmd("/bin/cp /usr/lib/libxml2* %s/usr/lib/", work_dir);
#ifdef __x86_64__
	execute_cmd("/bin/cp /usr/lib/x86_64-linux-gnu/libxml2.so* %s/usr/lib/", work_dir);
	execute_cmd("/bin/cp /usr/lib/x86_64-linux-gnu/libicuuc.so* %s/usr/lib/", work_dir);
	execute_cmd("/bin/cp /usr/lib/x86_64-linux-gnu/libicudata.so* %s/usr/lib/", work_dir);
	execute_cmd("/bin/cp /usr/lib/x86_64-linux-gnu/libstdc++.so* %s/usr/lib/", work_dir);
	execute_cmd("/bin/cp /usr/lib/x86_64-linux-gnu/libssl* %s/usr/lib/", work_dir);
	execute_cmd("/bin/cp /usr/lib/x86_64-linux-gnu/libcrypto* %s/usr/lib/", work_dir);
#endif
	execute_cmd("/bin/cp /usr/bin/php* %s/usr/bin", work_dir);
	execute_cmd("chmod +rx %s/Main.php", work_dir);
}

void copy_perl_runtime(char *work_dir)
{

	copy_shell_runtime(work_dir);
	execute_cmd("/bin/mkdir -p %s/usr/bin", work_dir);
	execute_cmd("/bin/mkdir %s/usr/lib", work_dir);
	execute_cmd("/bin/cp /usr/lib/libperl* %s/usr/lib/", work_dir);
	execute_cmd("/bin/cp /usr/bin/perl* %s/usr/bin", work_dir);
}

void copy_freebasic_runtime(char *work_dir)
{

	copy_shell_runtime(work_dir);
	execute_cmd("/bin/mkdir -p %s/usr/local/lib", work_dir);
	execute_cmd("/bin/mkdir -p %s/usr/local/bin", work_dir);
	execute_cmd("/bin/cp /usr/local/lib/freebasic %s/usr/local/lib/", work_dir);
	execute_cmd("/bin/cp /usr/local/bin/fbc %s/", work_dir);
	execute_cmd("/bin/cp -a /lib32/* %s/lib/", work_dir);
}

void copy_mono_runtime(char *work_dir)
{

	copy_shell_runtime(work_dir);
	execute_cmd("/bin/mkdir -p %s/usr/bin", work_dir);
	execute_cmd("/bin/mkdir %s/proc", work_dir);
	execute_cmd("/bin/mkdir -p %s/usr/lib/mono/2.0", work_dir);
	execute_cmd("/bin/cp -a /usr/lib/mono %s/usr/lib/", work_dir);
	execute_cmd("/bin/mkdir -p %s/usr/lib64/mono/2.0", work_dir);
	execute_cmd("/bin/cp -a /usr/lib64/mono %s/usr/lib64/", work_dir);

	execute_cmd("/bin/cp /usr/lib/libgthread* %s/usr/lib/", work_dir);

	execute_cmd("/bin/mount -o bind /proc %s/proc", work_dir);
	execute_cmd("/bin/cp /usr/bin/mono* %s/usr", work_dir);

	execute_cmd("/bin/cp /usr/lib/libgthread* %s/usr/lib/", work_dir);
	execute_cmd("/bin/cp /lib/libglib* %s/lib/", work_dir);
	execute_cmd("/bin/cp /lib/tls/i686/cmov/lib* %s/lib/tls/i686/cmov/",
				work_dir);
	execute_cmd("/bin/cp /lib/libpcre* %s/lib/", work_dir);
	execute_cmd("/bin/cp /lib/ld-linux* %s/lib/", work_dir);
#ifdef __x86_64__
	execute_cmd("/bin/cp /lib64/ld-linux* %s/lib64/", work_dir);
	execute_cmd("/bin/mkdir -p %s/usr/lib/x86_64-linux-gnu", work_dir);
	execute_cmd("/bin/cp /usr/lib/x86_64-linux-gnu/libm.so.6 %s/usr/lib/x86_64-linux-gnu/", work_dir);
	execute_cmd("/bin/cp /usr/lib/x86_64-linux-gnu/librt.so.1 %s/usr/lib/x86_64-linux-gnu/", work_dir);
	execute_cmd("/bin/cp /usr/lib/x86_64-linux-gnu/libpthread.so.0 %s/usr/lib/x86_64-linux-gnu/", work_dir);
	execute_cmd("/bin/cp /usr/lib/x86_64-linux-gnu/libgcc_s.so.1 %s/usr/lib/x86_64-linux-gnu/", work_dir);
	execute_cmd("/bin/cp /usr/lib/x86_64-linux-gnu/libc.so.6 %s/usr/lib/x86_64-linux-gnu/", work_dir);
	execute_cmd("/bin/cp /lib64/ld-linux-x86-64.so.2 %s/lib64", work_dir);
#endif
	execute_cmd("/bin/mkdir -p %s/home/judge", work_dir);
	execute_cmd("/bin/chown judge %s/home/judge", work_dir);
	execute_cmd("/bin/mkdir -p %s/etc", work_dir);
	execute_cmd("/bin/grep judge /etc/passwd>%s/etc/passwd", work_dir);
}

void copy_lua_runtime(char *work_dir)
{

	copy_shell_runtime(work_dir);
	execute_cmd("mkdir -p %s/usr/bin", work_dir);
	execute_cmd("/bin/mkdir -p %s/usr/local/lib", work_dir);
	execute_cmd("/bin/mkdir -p %s/usr/local/bin", work_dir);
	execute_cmd("/bin/cp /usr/bin/lua %s/usr/bin", work_dir);
}

void copy_sql_runtime(char *work_dir)
{

	copy_shell_runtime(work_dir);
	execute_cmd("mkdir -p %s/usr/bin", work_dir);
	execute_cmd("/bin/cp /usr/bin/sqlite3 %s/usr/bin", work_dir);
#ifdef __mips__
	execute_cmd("/bin/cp /lib64/libedit.so.0 %s/lib64/", work_dir);
	execute_cmd("/bin/cp /lib64/libm.so.6 %s/lib64/", work_dir);
	execute_cmd("/bin/cp /lib64/libdl.so.2 %s/lib64/", work_dir);
	execute_cmd("/bin/cp /lib64/libz.so.1 %s/lib64/", work_dir);
	execute_cmd("/bin/cp /lib64/libpthread.so.0 %s/lib64/", work_dir);
	execute_cmd("/bin/cp /lib64/libc.so.6 %s/lib64/", work_dir);
	execute_cmd("/bin/cp /lib64/libtinfo.so.6 %s/lib64/", work_dir);
#endif
#ifdef __i386__
	execute_cmd("/bin/cp /usr/lib/i386-linux-gnu/libsqlite3.so.0*   %s/lib/", work_dir);
	execute_cmd("/bin/cp /lib/i386-linux-gnu/libreadline.so.6*   %s/lib/", work_dir);
	execute_cmd("/bin/cp /lib/i386-linux-gnu/libc.so.6*  %s/lib/", work_dir);
	execute_cmd("/bin/cp /lib/i386-linux-gnu/libpthread.so.0 %s/lib/", work_dir);
	execute_cmd("/bin/cp /lib/i386-linux-gnu/libdl.so.2* %s/lib/", work_dir);
	execute_cmd("/bin/cp /lib/i386-linux-gnu/libtinfo.so.5* %s/lib/", work_dir);
	execute_cmd("/bin/cp /lib/i386-linux-gnu/libedit.so.0 %s/lib/", work_dir);
	execute_cmd("/bin/cp /lib/i386-linux-gnu/libm.so.6* %s/lib/", work_dir);
	execute_cmd("/bin/cp /lib/i386-linux-gnu/libz.so.1 %s/lib/", work_dir);
	execute_cmd("/bin/cp /lib/i386-linux-gnu/libtinfo.so.6* %s/lib/", work_dir);
#endif
#ifdef __x86_64__
	execute_cmd("/bin/cp /usr/lib/x86_64-linux-gnu/libsqlite3.so.0   %s/lib/", work_dir);
	execute_cmd("/bin/cp /lib/x86_64-linux-gnu/libreadline.so.6   %s/lib64/", work_dir);
	execute_cmd("/bin/cp /lib/x86_64-linux-gnu/libc.so.6  %s/lib64/", work_dir);
	execute_cmd("/bin/cp /lib/x86_64-linux-gnu/libpthread.so.0 %s/lib64/", work_dir);
	execute_cmd("/bin/cp /lib/x86_64-linux-gnu/libdl.so.2 %s/lib64/", work_dir);
	execute_cmd("/bin/cp /lib/x86_64-linux-gnu/libtinfo.so.5 %s/lib64/", work_dir);
	execute_cmd("/bin/cp /lib/x86_64-linux-gnu/libedit.so.0 %s/lib64/", work_dir);
	execute_cmd("/bin/cp /lib/x86_64-linux-gnu/libm.so.6 %s/lib64/", work_dir);
	execute_cmd("/bin/cp /lib/x86_64-linux-gnu/libz.so.1 %s/lib64/", work_dir);
	execute_cmd("/bin/cp /lib/x86_64-linux-gnu/libtinfo.so.6 %s/lib64/", work_dir);
#endif
}

void copy_js_runtime(char *work_dir)
{
	execute_cmd("mkdir -p %s/usr/bin", work_dir);
	execute_cmd("mkdir -p %s/dev", work_dir);
	execute_cmd("/bin/mount -o bind /dev %s/dev", work_dir);
	execute_cmd("/bin/mount -o remount,ro %s/dev", work_dir);
	execute_cmd("/bin/mkdir -p %s/usr/lib %s/lib/i386-linux-gnu/ %s/lib64/", work_dir, work_dir, work_dir);
	execute_cmd("/bin/cp /lib/i386-linux-gnu/libz.so.*  %s/lib/i386-linux-gnu/", work_dir);
	execute_cmd("/bin/cp /usr/lib/i386-linux-gnu/libuv.so.*  %s/lib/i386-linux-gnu/", work_dir);
	execute_cmd("/bin/cp /usr/lib/i386-linux-gnu/libicui18n.so.*  %s/lib/i386-linux-gnu/", work_dir);
	execute_cmd("/bin/cp /usr/lib/i386-linux-gnu/libicuuc.so.*  %s/lib/i386-linux-gnu/", work_dir);
	execute_cmd("/bin/cp /usr/lib/i386-linux-gnu/libicudata.so.*  %s/lib/i386-linux-gnu/", work_dir);
	execute_cmd("/bin/cp /lib/i386-linux-gnu/libtinfo.so.*  %s/lib/i386-linux-gnu/", work_dir);

	execute_cmd("/bin/cp /usr/lib/i386-linux-gnu/libcares.so.*  %s/lib/i386-linux-gnu/", work_dir);
	execute_cmd("/bin/cp /usr/lib/libv8.so.*  %s/lib/i386-linux-gnu/", work_dir);
	execute_cmd("/bin/cp /lib/i386-linux-gnu/libssl.so.*  %s/lib/i386-linux-gnu/", work_dir);
	execute_cmd("/bin/cp /lib/i386-linux-gnu/libcrypto.so.*  %s/lib/i386-linux-gnu/", work_dir);
	execute_cmd("/bin/cp /lib/i386-linux-gnu/libdl.so.*  %s/lib/i386-linux-gnu/", work_dir);
	execute_cmd("/bin/cp /lib/i386-linux-gnu/librt.so.*  %s/lib/i386-linux-gnu/", work_dir);
	execute_cmd("/bin/cp /usr/lib/i386-linux-gnu/libstdc++.so.*  %s/lib/i386-linux-gnu/", work_dir);
	execute_cmd("/bin/cp /lib/i386-linux-gnu/libpthread.so.*  %s/lib/i386-linux-gnu/", work_dir);
	execute_cmd("/bin/cp /lib/i386-linux-gnu/libc.so.6  %s/lib/i386-linux-gnu/", work_dir);
	execute_cmd("/bin/cp /lib/i386-linux-gnu/libm.so.6  %s/lib/i386-linux-gnu/", work_dir);
	execute_cmd("/bin/cp /lib/i386-linux-gnu/libgcc_s.so.1  %s/lib/i386-linux-gnu/", work_dir);
	execute_cmd("/bin/cp /lib/ld-linux.so.*  %s/lib/", work_dir);

#ifdef __x86_64__
	execute_cmd("/bin/mkdir -p %s/usr/lib/x86_64-linux-gnu/ %s/lib/x86_64-linux-gnu/", work_dir, work_dir);
	execute_cmd("/bin/cp /usr/lib/libv8.so.*  %s/usr/lib/", work_dir);
	execute_cmd("/bin/cp /usr/lib/x86_64-linux-gnu/libcares.so.* %s/usr/lib/x86_64-linux-gnu/", work_dir);
	execute_cmd("/bin/cp /lib/x86_64-linux-gnu/libz.so.* %s/lib/x86_64-linux-gnu/", work_dir);
	execute_cmd("/bin/cp /usr/lib/x86_64-linux-gnu/libuv.so.* %s/lib/x86_64-linux-gnu/", work_dir);
	execute_cmd("/bin/cp /lib/x86_64-linux-gnu/librt.so.* %s/lib/x86_64-linux-gnu/", work_dir);
	execute_cmd("/bin/cp /lib/x86_64-linux-gnu/libpthread.so.* %s/lib/x86_64-linux-gnu/", work_dir);
	execute_cmd("/bin/cp /lib/x86_64-linux-gnu/libdl.so.* %s/lib/x86_64-linux-gnu/", work_dir);
	execute_cmd("/bin/cp /lib/x86_64-linux-gnu/libssl.so.* %s/lib/x86_64-linux-gnu/", work_dir);
	execute_cmd("/bin/cp /lib/x86_64-linux-gnu/libcrypto.so.* %s/lib/x86_64-linux-gnu/", work_dir);
	execute_cmd("/bin/cp /usr/lib/x86_64-linux-gnu/libicui18n.so.* %s/lib/x86_64-linux-gnu/", work_dir);
	execute_cmd("/bin/cp /usr/lib/x86_64-linux-gnu/libicuuc.so.* %s/lib/x86_64-linux-gnu/", work_dir);
	execute_cmd("/bin/cp /usr/lib/x86_64-linux-gnu/libstdc++.so.* %s/lib/x86_64-linux-gnu/", work_dir);
	execute_cmd("/bin/cp /lib/x86_64-linux-gnu/libm.so.* %s/lib/x86_64-linux-gnu/", work_dir);
	execute_cmd("/bin/cp /lib/x86_64-linux-gnu/libgcc_s.so.* %s/lib/x86_64-linux-gnu/", work_dir);
	execute_cmd("/bin/cp /lib/x86_64-linux-gnu/libc.so.* %s/lib/x86_64-linux-gnu/", work_dir);
	execute_cmd("/bin/cp /lib64/ld-linux-x86-64.so.* %s/lib64/", work_dir);
	execute_cmd("/bin/cp /usr/lib/x86_64-linux-gnu/libicudata.so.* %s/lib/x86_64-linux-gnu/", work_dir);
#endif
	execute_cmd("/bin/cp /usr/bin/node %s/usr/bin", work_dir);
}

std::string removeExtension(const std::string& src_path) {
    size_t last_dot = src_path.find_last_of('.');
    if (last_dot != std::string::npos) {
        return src_path.substr(0, last_dot);
    }
    return src_path;
}

void run_solution(int &lang, char *work_dir, double &time_lmt, int &usedtime,
				  int &mem_lmt, char *data_file_path, int p_id ,int leetcode, char *src_pth) 
{
	std::string src_path_str(src_pth); 
    std::string prefix = removeExtension(src_path_str);
    char* class_name_cstr = new char[prefix.size() + 1];
    std::strcpy(class_name_cstr, prefix.c_str());
	char *const envp[] = {(char *const)"PYTHONIOENCODING=utf-8",
						  (char *const)"LANG=zh_CN.UTF-8",
						  (char *const)"LANGUAGE=zh_CN.UTF-8",
						  (char *const)"LC_ALL=zh_CN.utf-8", NULL};
	if (nice(19) != 19)
		printf("......................renice fail... \n");
	if (chdir(work_dir))
	{
		write_log("Working directory :%s switch fail...", work_dir);
		exit(-4);
	}
	if (lang == 18)
	{
		execute_cmd("/usr/bin/sqlite3 %s/data.db < %s", work_dir, data_file_path);
		execute_cmd("/bin/chown judge %s/data.db", work_dir);
		stdin = freopen("Main.sql", "r", stdin);
	}
	else
	{
		char noip_file_name[BUFFER_SIZE];
		sprintf(noip_file_name, "%s/data/%d/input.name", oj_home, p_id);
		if (DEBUG)
			printf("\n---------NOIP filename:%s\n", noip_file_name);
		if (access(noip_file_name, R_OK) == -1)
		{ 
			if (copy_data)
			{
				stdin = freopen("data.in", "r", stdin);
			}
			else
			{
				printf("infile: [%s]\n", data_file_path);
				stdin = freopen(data_file_path, "r", stdin);
			}
		}
	}
	execute_cmd("touch %s/user.out", work_dir);

	if (copy_data)
	{
		execute_cmd("chgrp judge %s/user.out %s/data.in", work_dir, work_dir);
		execute_cmd("chmod 740 %s/data.in", work_dir);
	}
	execute_cmd("chmod 760 %s/user.out", work_dir);
	if (
		(!use_docker) && lang != 3 && lang != 5 && lang != 20 && lang != 9 && !(lang == 6 && python_free))
	{

		if (DEBUG)
			printf("chroot...............................................\n");
	}
	else
	{
		if (DEBUG)
			printf("Skiping chroot........................................\n");
	}
	printf("\nopenning user.out\n");
	stdout = freopen("user.out", "w", stdout);
	stderr = freopen("error.out", "a+", stderr);
	ptrace(PTRACE_TRACEME, 0, NULL, NULL);
	if (
		(!use_docker) && lang != LANG_JAVA && lang != LANG_PHP && lang != LANG_BASH && lang != LANG_COBOL && lang != LANG_MATLAB && lang != LANG_CSHARP && !(lang == LANG_PYTHON && python_free))
	{
		if (chroot(work_dir))
			;
	}
	else
	{
		// vm script language don't chroot within docker
	}
	while (setgid(1536) != 0)
		sleep(1);
	while (setuid(1536) != 0)
		sleep(1);
	while (setresuid(1536, 1536, 1536) != 0)
		sleep(1);

	struct rlimit LIM; 
	if (time_limit_to_total)
		LIM.rlim_cur = (time_lmt / cpu_compensation - usedtime / 1000.0f) + 1;
	else
		LIM.rlim_cur = time_lmt / cpu_compensation + 1;
	LIM.rlim_max = LIM.rlim_cur + 1;
	alarm(0);
	if (time_lmt / cpu_compensation > 1)
		alarm(time_lmt / cpu_compensation);
	else
		alarm(1);
	LIM.rlim_max = STD_F_LIM + STD_MB;
	LIM.rlim_cur = STD_F_LIM;
	switch (lang)
	{
	case LANG_GO:
	case LANG_CSHARP: 
	case LANG_JAVA:	  
		break;
	case LANG_RUBY:	  
	case LANG_PYTHON: 
	case LANG_SCHEME:
	case LANG_JS:
	case LANG_MATLAB:
		LIM.rlim_cur = LIM.rlim_max = 200;
		break;
	case LANG_BASH: 
		LIM.rlim_cur = LIM.rlim_max = 3;
		break;
	default:
		LIM.rlim_cur = LIM.rlim_max = 1;
	}
	LIM.rlim_cur = STD_MB << 8;
	LIM.rlim_max = STD_MB << 8;
	LIM.rlim_cur = STD_MB * mem_lmt / 2 * 3;
	LIM.rlim_max = STD_MB * mem_lmt * 2;
	switch (lang)
	{
	case LANG_C:
	case LANG_CPP:
	case LANG_PASCAL:
	case LANG_OBJC:
	case LANG_FREEBASIC:
	case LANG_CLANG:
	case LANG_CLANGPP:
	case LANG_GO:
	case LANG_FORTRAN:
	case LANG_COBOL:
		execle("./Main", "./Main", (char *)NULL, envp);
		break;
	case LANG_JAVA:
		sprintf(java_xmx, "-Xmx%dM", mem_lmt);
		if(leetcode==1){
			char mem_lmt_str[32];
			sprintf(mem_lmt_str, "%d", mem_lmt);
			printf("work_dir:%s",work_dir);
			execle("/bin/bash", "/bin/bash", "/home/judge/leetcode_template/java/run.sh", work_dir, mem_lmt_str,(char *)NULL, envp);
		}
		else{
			execle("/usr/bin/java", "/usr/bin/java", java_xmx, 
			   class_name_cstr, (char *)NULL, envp);
		}
		
		break;
	case LANG_RUBY:
		execle("/usr/bin/ruby", "/usr/bin/ruby", "Main.rb", (char *)NULL, envp);
		break;
	case LANG_BASH: 
		execle("/bin/bash", "/bin/bash", "Main.sh", (char *)NULL, envp);
		break;
	case LANG_PYTHON: 
		printf("executing python");
		if (!py2)
		{
			execle("/usr/bin/python2", "/usr/bin/python2", "Main.py", (char *)NULL, envp);
		}
		else
		{
			execle("/usr/bin/python3", "/usr/bin/python3", "Main.py", (char *)NULL, envp);
		}
		break;
	case LANG_PHP: 
		execle("/usr/bin/php", "/usr/bin/php", "Main.php", (char *)NULL, envp);
		break;
	case LANG_PERL: 
		execle("/usr/bin/perl", "/usr/bin/perl", "Main.pl", (char *)NULL, envp);
		break;
	case LANG_CSHARP: 
		execle("/usr/bin/mono", "/usr/bin/mono", "--debug", "Main.exe", (char *)NULL, envp);
		break;
	case LANG_SCHEME: 
		execle("/usr/bin/guile", "/usr/bin/guile", "Main.scm", (char *)NULL, envp);
		break;
	case LANG_LUA: 
		execle("/usr/bin/lua", "/usr/bin/lua", "Main.lua", (char *)NULL, envp);
		break;
	case LANG_JS: 
		execle("/usr/bin/node", "/usr/bin/node", "Main.js", (char *)NULL, envp);
		break;
	case LANG_SQL: 
		execle("/usr/bin/sqlite3", "/usr/bin/sqlite3", "data.db", (char *)NULL, envp);
		break;
	case LANG_MATLAB:																				   
		execl("/usr/bin/octave-cli", "/usr/bin/octave-cli", "-W", "-q", "-H", "Main.m", (char *)NULL); 
		break;
	}
	fflush(stderr);
	exit(0);
}

int fix_python_mis_judge(char *work_dir, int &ACflg, int &topmemory,
						 int mem_lmt)
{
	int comp_res = OJ_AC;

	comp_res = execute_cmd(
		"/bin/grep 'MemoryError'  %s/error.out", work_dir);

	if (!comp_res)
	{
		printf("Python need more Memory!");
		ACflg = OJ_ML;
		topmemory = mem_lmt * STD_MB;
	}

	return comp_res;
}

int fix_java_mis_judge(char *work_dir, int &ACflg, int &topmemory,
					   int mem_lmt)
{
	int comp_res = OJ_AC;
	execute_cmd("chmod 777 %s/error.out", work_dir);
	if (DEBUG)
		execute_cmd("cat %s/error.out", work_dir);
	comp_res = execute_cmd("/bin/grep 'Exception'  %s/error.out", work_dir);
	if (!comp_res)
	{
		printf("Exception reported\n");
		ACflg = OJ_RE;
	}
	execute_cmd("cat %s/error.out", work_dir);

	comp_res = execute_cmd(
		"/bin/grep 'java.lang.OutOfMemoryError'  %s/error.out", work_dir);

	if (!comp_res)
	{
		printf("JVM need more Memory!");
		ACflg = OJ_ML;
		topmemory = mem_lmt * STD_MB;
	}

	if (!comp_res)
	{
		printf("JVM need more Memory or Threads!");
		ACflg = OJ_ML;
		topmemory = mem_lmt * STD_MB;
	}
	comp_res = execute_cmd("/bin/grep 'Could not create'  %s/error.out",
						   work_dir);
	if (!comp_res)
	{
		printf("jvm need more resource,tweak -Xmx(OJ_JAVA_BONUS) Settings");
		ACflg = OJ_RE;
	}
	return comp_res;
}

float raw_text_judge(char *infile, char *outfile, char *userfile, int *total_mark)
{
	float mark = 0;
	int total = 0;
	FILE *in = fopen(infile, "r");
	if (fscanf(in, "%d", &total) != 1)
		return -1;
	fclose(in);
	FILE *out = fopen(outfile, "r");
	int num = 0;
	char *user_answer = (char *)malloc(4096);
	size_t user_length = 4095;
	size_t ans_length = 4095;
	float m[total + 1];
	char *ans[total + 1];
	*total_mark = 0;
	for (int i = 1; i <= total; i++)
	{
		ans[i] = (char *)malloc(4096);
		if (fscanf(out, "%d", &num) != 1)
			return -2;
		if (i == num)
		{
			if (fscanf(out, "%*[^\[][%f]", &m[num]) != 1)
				return -3;
			*total_mark += m[num];
			ans_length = getline(&ans[i], &ans_length, out);
			for (int j = ans_length - 1; '\n' == ans[i][j] || '\r' == ans[i][j]; j--)
			{
				ans[i][j] = '\0';
			}
		}
		else
		{
		}
	}
	fclose(out);
	FILE *user = fopen(userfile, "r");
	FILE *df = fopen("diff.out", "a");
	for (int i = 1; i <= total; i++)
	{
		if (fscanf(user, "%d", &num) == EOF)
			continue;
		user_length = getline(&user_answer, &user_length, user);
		int j = 0;
		for (j = user_length - 1; '\n' == user_answer[j] || '\r' == user_answer[j]; j--)
		{
			user_answer[j] = '\0';
		}
		if (num > 0 && num <= total)
		{
			if (strcasecmp(ans[num], user_answer) == 0 || strcasecmp(ans[num], "*") == 0)
			{
				mark += m[num];
			}
			else
			{
				if (raw_text_diff)
					fprintf(df, "%d:%s[%s] -%.1f\n", i, ans[i], user_answer, m[i]);
			}
			m[num] = 0;
		}
		free(ans[i]);
	}
	free(user_answer);
	fclose(user);
	fclose(df);
	return mark;
}

int special_judge(char *oj_home, int problem_id, char *infile, char *outfile,
				  char *userfile, double *pass_rate, int spj)
{

	pid_t pid;
	char spjpath[BUFFER_SIZE / 2];
	char tpjpath[BUFFER_SIZE / 2];
	if (DEBUG)
		printf("pid=%d\n", problem_id);
	execute_cmd("chown www-data:judge %s/data/%d/spj %s %s %s", oj_home, problem_id, infile, outfile, userfile);
	execute_cmd("chmod 750 %s/data/%d/spj %s %s %s", oj_home, problem_id, infile, outfile, userfile);

	pid = fork();
	int ret = 0;
	if (pid == 0)
	{

		while (setgid(1536) != 0)
			sleep(1);
		while (setuid(1536) != 0)
			sleep(1);
		while (setresuid(1536, 1536, 1536) != 0)
			sleep(1);

		struct rlimit LIM; 

		LIM.rlim_cur = 15;
		LIM.rlim_max = LIM.rlim_cur;
		alarm(0);
		alarm(10);

		LIM.rlim_max = STD_F_LIM + STD_MB;
		LIM.rlim_cur = STD_F_LIM;
		sprintf(spjpath, "%s/data/%d/spj", oj_home, problem_id);
		sprintf(tpjpath, "%s/data/%d/tpj", oj_home, problem_id);

		if (access(tpjpath, X_OK) == 0)
		{
			ret = execute_cmd("%s/data/%d/tpj %s %s %s 2>> diff.out ", oj_home, problem_id, infile, userfile, outfile); 
			if (DEBUG)
				printf("testlib spj return: %d\n", ret);
		}
		else if (access(spjpath, X_OK) == 0)
		{
			ret = execute_cmd("%s/data/%d/spj %s %s %s", oj_home, problem_id, infile, outfile, userfile); 
			if (DEBUG)
				printf("hustoj spj return: %d\n", ret);
		}
		else if (spj == 2)
		{
		}
		else
		{
			printf("spj tpj not found problem: %d\n", problem_id);
			ret = 1;
		}
		if (ret)
			exit(1);
		else
			exit(0);
	}
	else
	{
		int status;

		waitpid(pid, &status, 0);
		ret = WEXITSTATUS(status);
		if (DEBUG)
			printf("recorded spj: %d\n", ret);
	}
	return ret;
}

void judge_solution(int &ACflg, int &usedtime, double time_lmt, int spj,
					int p_id, char *infile, char *outfile, char *userfile, int &PEflg,
					int lang, char *work_dir, int &topmemory, int mem_lmt,
					int solution_id, int num_of_test, double *pass_rate)
{
	int comp_res;
	if (num_of_test == 0)
		num_of_test = 1.0;

	if (ACflg == OJ_AC)
	{
		int real_limit = 1000;
		if (time_limit_to_total)
		{ 
			real_limit = time_lmt * 1000;
			if (total_time > real_limit)
				ACflg = OJ_TL; 
			if (usedtime > real_limit)
				ACflg = OJ_TL; 
		}
		else if (num_of_test > 0)
		{ 
			real_limit = num_of_test * time_lmt * 1000;
			if (usedtime > time_lmt * 1000)
				ACflg = OJ_TL; 
		}
		else
		{								  
			real_limit = time_lmt * 1000;
			if (usedtime > real_limit)
				ACflg = OJ_TL;
			if (total_time > real_limit)
				ACflg = OJ_TL;
		}
	}
	if (topmemory > mem_lmt * STD_MB)
		ACflg = OJ_ML; 
	if (ACflg == OJ_AC)
	{
		if (spj)
		{
			comp_res = special_judge(oj_home, p_id, infile, outfile, userfile, pass_rate, spj);

			if (comp_res == 0)
				comp_res = OJ_AC;
			else
			{
				if (DEBUG)
					printf("fail test %s\n", infile);
				comp_res = OJ_WA;
			}
		}
		else
		{
			comp_res = compare(outfile, userfile, infile, userfile);
		}
		if (comp_res == OJ_WA)
		{
			ACflg = OJ_WA;
			if (DEBUG)
				printf("fail test %s\n", infile);
		}
		else if (comp_res == OJ_PE)
			PEflg = OJ_PE;
		ACflg = comp_res;
	}

	if (lang == LANG_JAVA)
	{
		comp_res = fix_java_mis_judge(work_dir, ACflg, topmemory, mem_lmt);
	}
	if (lang == LANG_PYTHON)
	{
		comp_res = fix_python_mis_judge(work_dir, ACflg, topmemory, mem_lmt);
	}
	if (usedtime > 30*1000)
		ACflg = OJ_TL; 

	if (PERFORMANCE==2){
		printf("\nuserfile:%s\n",userfile);
		char copy_cmd[256];
		snprintf(copy_cmd, sizeof(copy_cmd), "mkdir -p /home/judge/leetcode_outputs/%d", solution_id);
		printf("\nmake_cmd:%s\n",copy_cmd);
		execute_cmd(copy_cmd);
		snprintf(copy_cmd, sizeof(copy_cmd), "cp %s /home/judge/leetcode_outputs/%d/%s", userfile, solution_id, getFileNameFromPath(outfile));
		printf("\ncopy_cmd:%s\n",copy_cmd);
		execute_cmd(copy_cmd);
	}
}

int get_page_fault_mem(struct rusage &ruse, pid_t &pidApp)
{
	int m_vmpeak, m_vmdata, m_minflt;
	m_minflt = ruse.ru_minflt * getpagesize();
	if (0 && DEBUG)
	{
		m_vmpeak = get_proc_status(pidApp, "VmPeak:");
		m_vmdata = get_proc_status(pidApp, "VmData:");
		printf("VmPeak:%d KB VmData:%d KB minflt:%d KB\n", m_vmpeak, m_vmdata,
			   m_minflt >> 10);
	}
	return m_minflt;
}

void print_runtimeerror(char *infile, char *err)
{
	FILE *ferr = fopen("error.out", "a+");
	fprintf(ferr, "%s:%s\n", infile, err);
	fclose(ferr);
}

void clean_session(pid_t p)
{
	const char *pre = "ps awx -o \"\%p \%P\"|grep -w ";
	const char *post = " | awk \'{ print $1  }\'|xargs kill -9";
	execute_cmd("%s %d %s", pre, p, post);
	execute_cmd("ps aux |grep \\^judge|awk '{print $2}'|xargs kill");
}

void watch_solution(pid_t pidApp, char *infile, int &ACflg, int spj,
					char *userfile, char *outfile, int solution_id, int lang,
					int &topmemory, int mem_lmt, int &usedtime, double time_lmt, int &p_id,
					int &PEflg, char *work_dir)
{
	int tempmemory = 0;

	if (DEBUG)
		printf("pid=%d judging %s\n", pidApp, infile);

	int status, sig, exitcode;
	char white_code[256] = {0};
	white_code[0] = 1; 
	white_code[5] = 1;
	white_code[17] = 1;
	white_code[23] = 1;
	white_code[133] = 1;
	char buf[BUFFER_SIZE];

	struct user_regs_struct reg;
	struct rusage ruse;
	int first = true;
	int tick = 0;
	long outFileSize = get_file_size(outfile);
	while (1)
	{
		tick++;

		wait4(pidApp, &status, __WALL, &ruse); 
		if (first)
		{ 
			ptrace(PTRACE_SETOPTIONS, pidApp, NULL, PTRACE_O_TRACESYSGOOD | PTRACE_O_TRACEEXIT
			);
		}

		if (lang == LANG_JAVA ||
			lang == LANG_PHP ||
			lang == LANG_CSHARP ||
			lang == LANG_CLANG || lang == LANG_CLANGPP ||
			lang == LANG_JS ||
			lang == LANG_GO ||
			lang == LANG_MATLAB ||
			lang == LANG_COBOL)
		{
			tempmemory = get_page_fault_mem(ruse, pidApp);
		}
		else
		{ 
			tempmemory = get_proc_status(pidApp, "VmPeak:") << 10;
		}
		if (tempmemory > topmemory)
			topmemory = tempmemory;
		if (topmemory > mem_lmt * STD_MB)
		{
			if (DEBUG)
				printf("out of memory %d\n", topmemory);
			if (ACflg == OJ_AC)
				ACflg = OJ_ML;
			ptrace(PTRACE_KILL, pidApp, NULL, NULL);
			break;
		}
		

		if (WIFEXITED(status))
		{ 
			exitcode = WEXITSTATUS(status);
			char error[BUFFER_SIZE];
			if (exitcode)
			{
				ACflg = OJ_RE;
				sprintf(error, "\t    non-zero return = %d \n", exitcode);
				print_runtimeerror(infile + strlen(oj_home) + 5, error);
			}
			break;
		}
		if ((lang < LANG_RUBY || lang == LANG_BASH || lang == LANG_CSHARP) && get_file_size("error.out") && !oi_mode)
		{
			ACflg = OJ_RE;
			
			ptrace(PTRACE_KILL, pidApp, NULL, NULL);
			break;
		}

		if (((tick & 0xff) == 0x00) && (!spj) && get_file_size(userfile) > outFileSize * 2 + 1024)
		{
			ACflg = OJ_OL;
			ptrace(PTRACE_KILL, pidApp, NULL, NULL);
			break;
		}

		exitcode = WEXITSTATUS(status) % 256;
	
		if (white_code[exitcode]
			
		)
		{ 
			// go on and on
			;
		}
		else
		{

			if (DEBUG)
			{
				printf("status>>8=%d\n", exitcode);
			}
			if (ACflg == OJ_AC)
			{
				switch (exitcode) 
				{
				case SIGCHLD:
				case SIGALRM:
					alarm(0);
					if (DEBUG)
						printf("alarm:%g\n", time_lmt);
				case SIGKILL:
				case SIGXCPU:
					ACflg = OJ_TL;
					usedtime = time_lmt * 1000;
					if (DEBUG)
						printf("TLE:%d\n", usedtime);
					break;
				case SIGXFSZ:
					ACflg = OJ_OL;
					break;
				default:
					ACflg = OJ_RE;
				}
				print_runtimeerror(infile + strlen(oj_home) + 5, strsignal(exitcode));
				sprintf(buf, "adding: ' white_code[%d]=1; ' after judge_client:2836 for ", exitcode);
				print_runtimeerror(buf, strsignal(exitcode));
			}
			ptrace(PTRACE_KILL, pidApp, NULL, NULL); 

			break;
		}
		if (WIFSIGNALED(status))
		{
			sig = WTERMSIG(status);

			if (DEBUG)
			{
				printf("WTERMSIG=%d\n", sig);
				psignal(sig, NULL);
			}
			if (ACflg == OJ_AC)
			{
				switch (sig) 
				{
				case SIGCHLD:
				case SIGALRM:
					alarm(0);
				case SIGKILL:
				case SIGXCPU:
					ACflg = OJ_TL;
					break;
				case SIGXFSZ:
					ACflg = OJ_OL;
					break;

				default:
					ACflg = OJ_RE;
				}
				print_runtimeerror(infile + strlen(oj_home) + 5, strsignal(sig));
			}
			break;
		}
		/*comment from http://www.felix021.com/blog/read.php?1662
		 WIFSTOPPED: return true if the process is paused or stopped while ptrace is watching on it
		 WSTOPSIG: get the signal if it was stopped by signal
		 */
		if (!use_ptrace)
		{
			ptrace(PTRACE_SYSCALL, pidApp, NULL, NULL);
			continue;
		}
#ifdef __mips__
		// https://github.com/strace/strace/blob/master/linux/mips/syscallent-n32.h#L344
		ptrace(PTRACE_GETREGS, pidApp, NULL, &reg);
		call_id = (unsigned int)reg.REG_SYSCALL;
		if ((call_id > 1000 && call_id < 5000) || (lang == LANG_PYTHON && call_id < 5500) || call_id > 6500)
		{
			print("ptracing")
			ptrace(PTRACE_SYSCALL, pidApp, NULL, NULL);
			continue;
		}
		else
		{
			call_id = call_id % call_array_size;
#endif
#ifdef __arm__
			call_id = ptrace(PTRACE_GETREGS, pidApp, NULL, &reg);
			call_id = ((unsigned int)reg.REG_SYSCALL) % call_array_size;
#endif
#ifdef __aarch64__
			call_id = ptrace(PTRACE_GETREGS, pidApp, (void *)NT_ARM_SYSTEM_CALL, &reg);
			print_arm_regs(reg.regs);
			printf("return call_id:%d\n", call_id);
			call_id = ((unsigned int)reg.REG_SYSCALL) % call_array_size;
			printf("regist call_id:%d\n", call_id);
#endif
#ifdef __i386__
			call_id = ptrace(PTRACE_GETREGS, pidApp, NULL, &reg);
			call_id = ((unsigned int)reg.REG_SYSCALL) % call_array_size;
#endif
#ifdef __x86_64__
			call_id = ptrace(PTRACE_GETREGS, pidApp, NULL, &reg);
			call_id = ((unsigned int)reg.REG_SYSCALL) % call_array_size;
#endif

			if (record_call)
			{
				printf("new call id:%d\n", call_id);
				call_counter[call_id]++;
				printf("call %d: %d\n", call_id, call_counter[call_id]);
			}
			else if (call_counter[call_id])
			{
				call_counter[call_id]--;
			}
			else
			{ 
				ACflg = OJ_RE;
				char error[BUFFER_SIZE];
				sprintf(error,
						"[ERROR] solution_id:%d called a Forbidden system call:%u [%u]\n"
						" TO FIX THIS , ask admin to add the CALLID into corresponding LANG_XXV[] located at okcalls32/64.h ,\n"
						"and recompile judge_client. \n"
						"if you are admin and you don't know what to do ,\n"
						"中文解释查看知乎 https://zhuanlan.zhihu.com/p/24498599\n",
						solution_id, call_id, (unsigned int)reg.REG_SYSCALL);

				write_log(error);
				print_runtimeerror(infile + strlen(oj_home) + 5, error);
				ptrace(PTRACE_KILL, pidApp, NULL, NULL);
			}
			call_id = 0;
#ifdef __mips__
			
		}
#endif
		ptrace(PTRACE_SYSCALL, pidApp, NULL, NULL); 
		first = false;
		
	}
	ptrace(PTRACE_KILL, pidApp, NULL, NULL);													
	execute_cmd("kill -9 %d", pidApp);															 
	usedtime += (ruse.ru_utime.tv_sec * 1000 + ruse.ru_utime.tv_usec / 1000) * cpu_compensation; 
	usedtime += (ruse.ru_stime.tv_sec * 1000 + ruse.ru_stime.tv_usec / 1000) * cpu_compensation; 
}

void clean_workdir(char *work_dir)
{
	umount(work_dir);
	if (DEBUG)
	{
		if (PERFORMANCE==0) {
			printf("\ndebug copying \n");
			execute_cmd("cp -r %s /home/judge/log/", work_dir);

			execute_cmd("mkdir %s/log/ 2>/dev/null", work_dir);
			execute_cmd("/bin/mv %s/* %s/log/ 2>/dev/null", work_dir, work_dir);
			execute_cmd("/bin/rmdir %s/log/* 2>/dev/null", work_dir);
			execute_cmd("/bin/rm -rf %s/log/* 2>/dev/null", work_dir);
		}
		else {
			printf("\nremoving\n");
			execute_cmd("mkdir %s/log/ 2>/dev/null", work_dir);
			execute_cmd("/bin/mv %s/* %s/log/ 2>/dev/null", work_dir, work_dir);
			execute_cmd("/bin/rmdir %s/log/* 2>/dev/null", work_dir);
			execute_cmd("/bin/rm -rf %s/*", work_dir);
		}
	}
	else
	{
		execute_cmd("mkdir %s/log/ 2>/dev/null", work_dir);
		execute_cmd("/bin/mv %s/* %s/log/ 2>/dev/null", work_dir, work_dir);
		execute_cmd("/bin/rmdir %s/log/* 2>/dev/null", work_dir);
		execute_cmd("/bin/rm -rf %s/log/* 2>/dev/null", work_dir);
	}
	printf("finished clean");
}

void init_parameters(int argc, char **argv, int &solution_id,
					 int &runner_id)
{
	if (argc < 3)
	{
		fprintf(stderr, "HUSTOJ judge_client ver 20230823\n\n");
		fprintf(stderr, "Normal Usage:\n\t%s <solution_id> <runner_id>\n\n", argv[0]);
		fprintf(stderr, "Multi OJ with Specific home :\n\t%s <solution_id> <runner_id> [judge_base_path].\n\n",
				argv[0]);
		fprintf(stderr,
				"Debug with Specific home:\n\t%s <solution_id> <runner_id> [judge_base_path] [debug].\n\n",
				argv[0]);
		fprintf(stderr, "\n\n");
		fprintf(stderr, "Example:\n\tsudo %s 1001 0 /home/judge/ debug  \n\n", argv[0]);
		exit(1);
	}
	DEBUG = (argc > 4);

	if (argc > 5){
		std::string arg1 = argv[5];
		if (arg1 == "performance") {
			PERFORMANCE = 1;
		} else if (arg1 == "out") {
			PERFORMANCE = 2;
		}
	}

	record_call = (argc > 6);
	if (argc > 6)
	{
		strcpy(LANG_NAME, argv[6]);
	}
	if (argc > 3)
		strcpy(oj_home, argv[3]);
	else
		strcpy(oj_home, "/home/judge");

	if (chdir(oj_home))
		exit(-2); 

	solution_id = atoi(argv[1]);
	runner_id = atoi(argv[2]);
}
int get_sim(int solution_id, int lang, int pid, int &sim_s_id)
{
	char src_pth[BUFFER_SIZE];
	sprintf(src_pth, "Main.%s", lang_ext[lang]);
	int sim = execute_cmd("/usr/bin/sim.sh %s %d", src_pth, pid);
	FILE *pf;
	pf = fopen("sim", "r");
	if (!sim)
	{
		if (pf)
		{
			execute_cmd("/bin/mkdir ../data/%d/ac/ 2>/dev/null", pid);
			execute_cmd("/bin/cp %s ../data/%d/ac/%d.%s 2>/dev/null", src_pth, pid, solution_id,
						lang_ext[lang]);
			if (lang == 0)
				execute_cmd("/bin/ln ../data/%d/ac/%d.%s ../data/%d/ac/%d.%s 2>/dev/null", pid,
							solution_id, lang_ext[lang], pid, solution_id,
							lang_ext[lang + 1]);
			if (lang == 1)
				execute_cmd("/bin/ln ../data/%d/ac/%d.%s ../data/%d/ac/%d.%s 2>/dev/null", pid,
							solution_id, lang_ext[lang], pid, solution_id,
							lang_ext[lang - 1]);
		}
	}
	else
	{
		if (pf)
		{
			if (2 == fscanf(pf, "%d%d", &sim, &sim_s_id))
				;
		}
	}
	if (pf)
		fclose(pf);
	if (solution_id <= sim_s_id)
		sim = 0;
	return sim;
}

void mk_shm_workdir(char *work_dir)
{
	char shm_path[BUFFER_SIZE];
	sprintf(shm_path, "/ML-A100/public/run/research/tianyuzheng/hustoj%s", work_dir);
	execute_cmd("/bin/mkdir -p %s  2>/dev/null", shm_path);
	execute_cmd("/bin/ln -s %s %s/  2>/dev/null", shm_path, oj_home);
	execute_cmd("/bin/chown judge %s  2>/dev/null", shm_path);
	execute_cmd("chmod 777 %s  2>/dev/null", shm_path);
	sprintf(shm_path, "/ML-A100/public/run/research/tianyuzheng/hustoj%s/", oj_home);
	execute_cmd("/bin/ln -s %s/data %s  2>/dev/null", oj_home, shm_path);
}

int count_in_files(char *dirpath)
{
	const char *cmd = "ls -l %s/*.in|wc -l";
	int ret = 0;
	FILE *fjobs = read_cmd_output(cmd, dirpath);
	if (1 != fscanf(fjobs, "%d", &ret))
		printf("warning count files fail");
	;
	pclose(fjobs);

	return ret;
}

int get_test_file(char *work_dir, int p_id)
{
	char filename[BUFFER_SIZE / 2];
	char localfile[BUFFER_SIZE];
	time_t remote_date, local_date;
	int ret = 0;
	const char *cmd =
		" wget --post-data=\"gettestdatalist=1&time=1&pid=%d\" --load-cookies=cookie --save-cookies=cookie --keep-session-cookies -q -O - \"%s%s\"";
	FILE *fjobs = read_cmd_output(cmd, p_id, http_baseurl, http_apipath);
	while (fgets(filename, sizeof(filename) - 1, fjobs) != NULL)
	{

		if (1 != sscanf(filename, "%ld", &remote_date))
			printf("http remote time stamp read fail\n");
		if (fgets(filename, sizeof(filename) - 1, fjobs) == NULL)
			break;
		if (1 != sscanf(filename, "%s", filename))
			printf("http filename read fail\n");
		if (http_judge && (!data_list_has(filename)))
			data_list_add(filename);
		sprintf(localfile, "%s/data/%d/%s", oj_home, p_id, filename);
		if (DEBUG)
			printf("localfile[%s]\n", localfile);

		struct stat fst;
		stat(localfile, &fst);
		local_date = fst.st_mtime;

		if (access(localfile, F_OK) == -1 || local_date < remote_date)
		{

			if (strcmp(filename, "spj") == 0)
				continue;
			execute_cmd("/bin/mkdir -p %s/data/%d", oj_home, p_id);
			const char *cmd2 =
				" wget --post-data=\"gettestdata=1&filename=%d/%s\" --load-cookies=cookie --save-cookies=cookie --keep-session-cookies -q -O \"%s\"  \"%s%s\"";
			execute_cmd(cmd2, p_id, filename, localfile, http_baseurl, http_apipath);
			ret++;

			if (strcmp(filename, "spj.c") == 0)
			{
				if (access(localfile, F_OK) == 0)
				{
					const char *cmd3 = "gcc -o %s/data/%d/spj %s/data/%d/spj.c";
					execute_cmd(cmd3, oj_home, p_id, oj_home, p_id);
				}
			}
			if (strcmp(filename, "spj.cc") == 0)
			{
				if (access(localfile, F_OK) == 0)
				{
					const char *cmd4 =
						"g++ -o %s/data/%d/spj %s/data/%d/spj.cc";
					execute_cmd(cmd4, oj_home, p_id, oj_home, p_id);
				}
			}
		}
	}
	pclose(fjobs);

	return ret;
}

void print_call_array()
{
	printf("int LANG_%sV[CALL_ARRAY_SIZE]={", LANG_NAME);
	int i = 0;
	for (i = 0; i < call_array_size; i++)
	{
		if (call_counter[i] > 0)
		{
			printf("%d,", i);
		}
	}
	printf("0};\n");

	printf("int LANG_%sC[CALL_ARRAY_SIZE]={", LANG_NAME);
	for (i = 0; i < call_array_size; i++)
	{
		if (call_counter[i])
		{
			printf("%d,", call_counter[i]);
		}
	}
	printf("0};\n");
}

int has_mark_in_name = 0;

int mark_of_name(const char *name)
{
	int mark;
	printf("reading mark from %s \n", name);
	if (sscanf(name, "%*[^\[][%d]", &mark) == 1)
	{
		printf("reading mark %d \n", mark);
		has_mark_in_name = 1;
		return mark;
	}
	else
	{
		return 10;
	}
}

int same_subtask(char *last, char *cur)
{
	int i = 0;
	for (i = 0; last[i] != '.' && cur[i] != '.'; i++)
	{
		if (last[i] != cur[i])
		{
			break;
		}
	}
	return last[i] == cur[i];
}

#ifdef _mysql_h
void _update_model_mysql(char *model_id)
{
	char sql[BUFFER_SIZE];

	sprintf(sql,
			"UPDATE `models` SET `submit`=(SELECT count(*) FROM `solution` WHERE `model_id`=\'%s\' and problem_id>0) WHERE `model_id`=\'%s\'",
			model_id, model_id);
	if (mysql_real_query(conn, sql, strlen(sql)))
		write_log(mysql_error(conn));

	sprintf(sql,
			"UPDATE `models` SET `judged`=(SELECT count(DISTINCT `problem_id`) FROM `solution` WHERE `model_id`=\'%s\' AND `result`>=4) WHERE `model_id`=\'%s\'",
			model_id, model_id);
	if (mysql_real_query(conn, sql, strlen(sql)))
		write_log(mysql_error(conn));
}
#endif

void update_model(char *model_id)
{
#ifdef _mysql_h
	_update_model_mysql(model_id);
#endif
}

int main(int argc, char **argv)
{

	char work_dir[BUFFER_SIZE];
	char model_id[BUFFER_SIZE]; 
	char src_pth[BUFFER_SIZE];
	int solution_id = 1000;
	int runner_id = 0;
	int p_id, mem_lmt, lang, spj, leetcode, sim, sim_s_id, max_case_time = 0, cid = 0;
	double time_lmt;
	char time_space_table[BUFFER_SIZE * 100];
	int time_space_index = 0;

	init_parameters(argc, argv, solution_id, runner_id);

	init_judge_conf();

#ifdef _mysql_h
	if (!http_judge && !init_mysql_conn())
	{
		exit(0); 
	}
#endif
	sprintf(work_dir, "%s/run%s", oj_home, argv[2]);
	sprintf(lock_file, "%s/client%s.pid", oj_home, argv[2]);

	while (already_running())
	{
		syslog(LOG_ERR | LOG_DAEMON,
			   "This working directory is occupied !\n");
		printf("%s already has one judge_client in it!\n", work_dir);
		sleep(5);
	}

	if (shm_run)
	{
		mk_shm_workdir(work_dir);
	}
	else
	{
		execute_cmd("mkdir %s", work_dir);
	}

	clean_workdir(work_dir);

	printf("\nchdir\n");
	if (chdir(work_dir))
		exit(-3);
	printf("\nbefore httpjudge\n");
	if (http_judge)
		if (!system("/bin/ln -s ../cookie ./"))
			printf("cookie link fail \n");
	printf("\ngetting solution info\n");
	get_solution_info(solution_id, p_id, model_id, lang, cid);

	printf("cid:%d",cid);
	
	#ifdef _mysql_h
	if(cid==1001){
		char sql[BUFFER_SIZE];
		MYSQL_RES *res;
		MYSQL_ROW row;

		sprintf(sql,"SELECT target_lang FROM code_translation WHERE problem_id='%d'",p_id);
		mysql_real_query(conn, sql, strlen(sql));
		res = mysql_store_result(conn);
		row = mysql_fetch_row(res);
		printf("\nrow[0]%s\n",row[0]);
		if (strcmp(row[0], "Java") == 0) {
			lang = 3;
		}
		else if (strcmp(row[0], "C++") == 0) {
			lang = 1;
		}
		else if (strcmp(row[0], "Python") == 0) {
			lang = 6;
		}
		else {
			printf("\nUNSUPPORTED %s\n", row[0]);
			lang = 10;
		}
		printf("translate lang %d",lang);

	}
	#endif

	get_problem_info(p_id, time_lmt, mem_lmt, spj, leetcode);

	get_solution(solution_id, work_dir, lang, src_pth);

	printf("lang:%d",lang);

	if (lang == LANG_JAVA && leetcode==1)
	{
		std::string work_dir_str(work_dir);
		std::string command = "bash /home/judge/leetcode_template/java/copy_template.sh " + work_dir_str;
		const char *command_cstr = command.c_str();
		printf("%s/n", command_cstr);
		int result = system(command_cstr);
		if (result == 0)
		{
			printf("Shell script executed successfully.\n");
		}
		else
		{
			printf("Failed to execute shell script.\n");
		}
	}

	if (lang == LANG_PYTHON && leetcode==1)
	{
		std::string work_dir_str(work_dir);
		std::string command = "bash /home/judge/leetcode_template/python/copy_template.sh " + work_dir_str;
		const char *command_cstr = command.c_str();
		printf("%s/n", command_cstr);
		int result = system(command_cstr);
		if (result == 0)
		{
			printf("Shell script executed successfully.\n");
		}
		else
		{
			printf("Failed to execute shell script.\n");
		}
	}


	if (lang >= LANG_JAVA && lang != LANG_OBJC && lang != LANG_CLANG && lang != LANG_CLANGPP)
	{ 
		if (lang == 3)
		{
			execute_cmd("/bin/cp %s/etc/java0.policy %s/java.policy", oj_home, work_dir);
			execute_cmd("chmod 755 %s/java.policy", work_dir);
			execute_cmd("chown judge %s/java.policy", work_dir);
		}
	}
	if (time_lmt > 300 || time_lmt < 0)
		time_lmt = 300;
	if (mem_lmt > 4096 || mem_lmt < 1)
		mem_lmt = 4096;
	time_lmt = 120;
	mem_lmt = 512;
	if (PERFORMANCE!=0)
	{
		time_lmt = 300;
		mem_lmt = 512;
	}

	if (DEBUG){
		write_log("current timelmt: %g memlmt: %d\n", time_lmt, mem_lmt);
	}

	printf("current timelmt: %f memlmt: %d\n", time_lmt, mem_lmt);

	execute_cmd("chown judge %s/%s", work_dir, src_pth);
	execute_cmd("chown -R judge %s ", work_dir);
	execute_cmd("chmod -R 755 %s ", work_dir);
	if (shm_run){
		printf("shm_run\n");
		execute_cmd("chown judge /ML-A100/public/run/research/tianyuzheng/hustoj%s/%s", work_dir, src_pth);
		execute_cmd("chown -R judge /ML-A100/public/run/research/tianyuzheng/hustoj%s ", work_dir);
		execute_cmd("chmod -R 755 /ML-A100/public/run/research/tianyuzheng/hustoj%s ", work_dir);
	}

	int Compile_OK = 0;
	if (spj != 2)
	{
		Compile_OK = compile(lang, work_dir, leetcode, src_pth); 
	}
	if (Compile_OK != 0 && spj != 2)
	{
		write_log("compile ,exec  cp -r %s* /home/judge/log/bak_solution%d", work_dir, solution_id);
		addceinfo(solution_id);
		update_solution(solution_id, cid, OJ_CE, time_lmt, mem_lmt, 0, 0, 0, 0, 0.0); 
		if (!turbo_mode)
			update_model(model_id); 
		if (!turbo_mode)
			update_problem(p_id, cid);
#ifdef _mysql_h
		if (!http_judge)
			mysql_close(conn);
#endif
		clean_workdir(work_dir);
		exit(0);
	}
	else
	{
		write_log("compile true, Compile_OK:%d,spj:%d,solution_id%d", Compile_OK, spj, solution_id);
		if (!turbo_mode)
			update_solution(solution_id, cid, OJ_RI, time_lmt, mem_lmt, 0, 0, 0, 0, 0.0);
		umount(work_dir);
		if (shm_run){
			printf("shm_run\n");
			execute_cmd("chown judge /ML-A100/public/run/research/tianyuzheng/hustoj%s/%s", work_dir, src_pth);
			execute_cmd("chown -R judge /ML-A100/public/run/research/tianyuzheng/hustoj%s ", work_dir);
			execute_cmd("chmod -R 755 /ML-A100/public/run/research/tianyuzheng/hustoj%s ", work_dir);
		}
	}

	char fullpath[BUFFER_SIZE];
	char infile[BUFFER_SIZE / 10];
	char outfile[BUFFER_SIZE / 10];
	char userfile[BUFFER_SIZE / 10];
	sprintf(fullpath, "%s/data/%d", oj_home, p_id);
	printf("\nfullpath:%s\n",fullpath);

	dirent *dirp;
	if (p_id > 0 && http_judge && http_download == 1)
		get_test_file(work_dir, p_id);
	if (p_id > 0 && http_download == 2)
		execute_cmd("%s/src/install/rsync.sh %d", oj_home, p_id);

	struct dirent **namelist;
	int namelist_len;
    namelist_len = scandir(fullpath, &namelist, inFile, alphasort);
	if (p_id > 0 && namelist_len == -1)
	{

		write_log("No such dir:%s!\n", fullpath);
#ifdef _mysql_h
		if (!http_judge)
			mysql_close(conn);
#endif
		exit(-1);
	}
	else
	{
		if (DEBUG)
		{
			write_log("total test case:%d \n", namelist_len);
			for (int i = 0; i < namelist_len; i++)
			{
				write_log("test file %d : %s\n", i + 1, namelist[i]->d_name);
			}
		}
	}

	int ACflg, PEflg;
	ACflg = PEflg = OJ_AC;
	int namelen;
	int usedtime = 0, topmemory = 0;
	if (lang == LANG_BASH)
	{
		execute_cmd("busybox dos2unix Main.sh", work_dir);
	}
	if (!use_docker)
	{
		if (lang == LANG_RUBY)
			copy_ruby_runtime(work_dir);
		if (lang == LANG_BASH)
		{
			copy_bash_runtime(work_dir);
		}
		printf("pythonfree:%d",python_free);
		if (lang == LANG_PYTHON && !python_free){
			printf("copy python runtime");
			copy_python_runtime(work_dir);
		}
		if (lang == LANG_PHP)
			copy_php_runtime(work_dir);
		if (lang == LANG_PERL)
			copy_perl_runtime(work_dir);
		if (lang == LANG_OBJC)
			copy_objc_runtime(work_dir);
		if (lang == LANG_FREEBASIC)
			copy_freebasic_runtime(work_dir);
		if (lang == LANG_SCHEME)
			copy_guile_runtime(work_dir);
		if (lang == LANG_LUA)
			copy_lua_runtime(work_dir);
		if (lang == LANG_JS)
			copy_js_runtime(work_dir);
		if (lang == LANG_SQL)
			copy_sql_runtime(work_dir);
	}

	double pass_rate = 0.0;
	float mark = 0;
	int total_mark = 0, get_mark = 0;
	int finalACflg = ACflg;
	if (p_id == 0)
	{ 
		printf("running a custom input...\n");
		get_custominput(solution_id, work_dir);
		init_syscalls_limits(lang);
		pid_t pidApp = fork();

		if (pidApp == 0)
		{
			run_solution(lang, work_dir, time_lmt, usedtime, mem_lmt, (char *)"data.in", p_id, leetcode, src_pth);
		}
		else
		{
			watch_solution(pidApp, infile, ACflg, spj, userfile, outfile,
						   solution_id, lang, topmemory, mem_lmt, usedtime, time_lmt,
						   p_id, PEflg, work_dir);
		}
		if (DEBUG)
			write_log("custom running result:%d PEflg:%d\n", ACflg, PEflg);
		if (ACflg == OJ_RE || get_file_size("error.out") > 0)
		{
			if (DEBUG)
				write_log("add RE info of %d..... \n", solution_id);
			addreinfo(solution_id);
		}
		else
		{
			addcustomout(solution_id);
		}
		update_solution(solution_id, cid, OJ_TR, time_lmt, mem_lmt, usedtime, topmemory >> 10, 0, 0, 0);
		clean_workdir(work_dir);
		exit(0);
	}
	num_of_test = namelist_len;

	if (num_of_test == 0)
	{
		print_runtimeerror((char *)"no test data ", (char *)" no *.in file found");
		ACflg = OJ_RE;
		finalACflg = OJ_RE;
	}
	char last_name[BUFFER_SIZE];
	int minus_mark = 0;
	for (int i = 0; (oi_mode || ACflg == OJ_AC || ACflg == OJ_PE) && i < namelist_len; i++)
	{
		dirp = namelist[i];
		printf("\ntesting:%s\n",dirp->d_name);

		namelen = isInFile(dirp->d_name); 
		printf("\nnamelen:%d\n",namelen);
		if (namelen == 0){
			printf("\ncontinue1\n");
			continue;
		}
		printf("\nbefore mark\n");
		mark = mark_of_name(dirp->d_name);
		total_mark += mark;
		printf("\nbefore http\n");
		if (http_judge && (http_download == 1) && (!data_list_has(dirp->d_name)))
		{
			printf("\ncontinue2\n");
			continue;
		}
		printf("\npreparing\n");
		prepare_files(dirp->d_name, namelen, infile, p_id, work_dir, outfile,
					  userfile, runner_id);
		printf("\npreparing end\n");	  
		if (access(outfile, R_OK) == -1)
		{
			char error[BUFFER_SIZE];
			printf("\nmissing out\n");
			sprintf(error, "missing out file %s\n", basename(outfile));
			print_runtimeerror(infile + strlen(oj_home) + 5, error);
			ACflg = OJ_RE;
		}

		init_syscalls_limits(lang);

		pid_t pidApp = fork(); 
		printf("\nafter fork\n");
		if (pidApp == 0) 
		{
			if (spj == 2)
			{
				exit(0);
			}
			printf("\nrunning solution\n");
			run_solution(lang, work_dir, time_lmt, usedtime, mem_lmt, infile, p_id, leetcode, src_pth);
			printf("\nfinished running solution\n");
		}
		else
		{ 
			if (spj != 2)
				watch_solution(pidApp, infile, ACflg, spj, userfile, outfile,
							   solution_id, lang, topmemory, mem_lmt, usedtime, time_lmt,
							   p_id, PEflg, work_dir);
			kill(pidApp, 9);
			printf("%s: mem=%d time=%d\n", infile + strlen(oj_home) + 5, topmemory, usedtime);
			total_time += usedtime;
			printf("time:%d/%d\n", usedtime, total_time);
			judge_solution(ACflg, usedtime, time_lmt, spj, p_id, infile,
						   outfile, userfile, PEflg, lang, work_dir, topmemory,
						   mem_lmt, solution_id, num_of_test, &pass_rate);
			time_space_index += sprintf(time_space_table + time_space_index, "%s:%s mem=%dk time=%dms\n", infile + strlen(oj_home) + 5, jresult[ACflg], topmemory / 1024, usedtime);

			if (use_max_time)
			{
				max_case_time =
					usedtime > max_case_time ? usedtime : max_case_time;
			}
			usedtime = 0;
		}
		if (oi_mode)
		{
			if (ACflg == OJ_AC)
			{
				++pass_rate;
				get_mark += mark;
				if (same_subtask(last_name, dirp->d_name))
				{ 
					if (minus_mark >= 0)
					{						
						minus_mark += mark; 
					}
					else
					{
						get_mark -= mark; 
					}
				}
				else
				{
					minus_mark = mark; 
				}
			}
			else
			{
				if (same_subtask(last_name, dirp->d_name))
				{ 
					if (minus_mark >= 0)
						get_mark -= minus_mark; 
				}
				minus_mark = -1; 
			}
			if (finalACflg < ACflg)
			{
				finalACflg = ACflg;
			}

			if (time_limit_to_total && (ACflg == OJ_TL))
			{
				printf("\ntime out ,break,total_time%d >time_lmt%g\n",total_time,time_lmt);
				break; 
			}
			if (ACflg!=OJ_AC){
				printf("\nbreak,result:%d,finalresult:%d\n",ACflg,finalACflg);
				break;
			}
			ACflg = OJ_AC;
		}
#ifdef _mysql_h
		if (!http_judge)
			check_mysql_conn();
#endif
		strcpy(last_name, dirp->d_name);
		printf("lastname%s",last_name);
	}
	if (ACflg == OJ_AC && PEflg == OJ_PE)
		ACflg = OJ_PE;
	if (sim_enable && ACflg == OJ_AC && (!oi_mode || finalACflg == OJ_AC))
	{ 
		sim = get_sim(solution_id, lang, p_id, sim_s_id);
	}
	else
	{
		sim = 0;
	}
	if ((oi_mode && finalACflg == OJ_RE) || ACflg == OJ_RE)
	{
		if (DEBUG)
			printf("add RE info of %d..... \n", solution_id);
		FILE *df = fopen("error.out", "a");
		fprintf(df, "----time_space_table:----\n%s\n", time_space_table);
		fclose(df);
		addreinfo(solution_id);
	}
	if (use_max_time)
	{
		if (DEBUG)
			write_log("use max case time:%d\n", max_case_time);
		usedtime = max_case_time;
	}
	else
	{
		if (DEBUG)
			write_log("use total time:%d\n", total_time);
		usedtime = total_time;
	}

	printf("PERFORMANCE %d\n", PERFORMANCE);
	if (PERFORMANCE==1)
	{
		FILE *file_pointer;
		file_pointer = fopen("/home/judge/not_leet_code_performance.csv", "r");
		if (file_pointer != NULL)
		{
			fclose(file_pointer);
			file_pointer = fopen("/home/judge/not_leet_code_performance.csv", "a");
		}
		else
		{ 
			file_pointer = fopen("/home/judge/not_leet_code_performance.csv", "a+");
			fprintf(file_pointer, "problem_id,topmemory(KB),total_time\n"); 
		}
		fprintf(file_pointer, "%d,%d,%d\n", p_id, topmemory / 1024, total_time); 
		fclose(file_pointer);
	}

	if (spj != 2)
	{
		if (oi_mode)
		{
			if (num_of_test > 0)
			{
				pass_rate /= num_of_test;
			}
			if (total_mark > 0 && has_mark_in_name)
			{
				pass_rate = get_mark;
				if (total_mark > 100)
					pass_rate /= total_mark;
				else
					pass_rate /= 100.0;
			}
			update_solution(solution_id, cid, finalACflg, time_lmt, mem_lmt, usedtime, topmemory >> 10, sim,
							sim_s_id, pass_rate);
		}
		else
		{
			if (ACflg == OJ_AC)
				pass_rate = 1.0;
			else
				pass_rate = 0.0;
			update_solution(solution_id, cid, ACflg, time_lmt, mem_lmt, usedtime, topmemory >> 10, sim,
							sim_s_id, pass_rate);
		}
	}
	else
	{
		char src_pth[BUFFER_SIZE];
		printf("raw text judge %d \n", p_id);
		sprintf(src_pth, "Main.%s", lang_ext[lang]);
		mark = raw_text_judge(infile, outfile, src_pth, &total_mark);
		printf("raw_text_mark:%.1f\n", mark);
		if (mark >= 0 && mark <= total_mark)
			pass_rate = mark;
		pass_rate /= 100.0;
		if (mark == total_mark)
			finalACflg = ACflg = OJ_AC;
		else
			finalACflg = ACflg = OJ_WA;
		update_solution(solution_id, cid, finalACflg, time_lmt, mem_lmt, total_mark, mark, sim, sim_s_id, pass_rate);
	}

	FILE *df = fopen("diff.out", "a");
	fprintf(df, "time_space_table:\n%s\n", time_space_table);
	fclose(df);
	if (DEBUG)
		printf("ACflg:%d\n", ACflg);
	printf("final result:%d\n", finalACflg);
	if (ACflg != OJ_RE && finalACflg != OJ_RE)
		adddiffinfo(solution_id);
	if (!turbo_mode)
		update_model(model_id); 
	if (!turbo_mode)
		update_problem(p_id, cid);
	clean_workdir(work_dir);

	if (DEBUG)
		write_log("result=%d", oi_mode ? finalACflg : ACflg);
#ifdef _mysql_h
	if (!http_judge)
		mysql_close(conn);
#endif
	if (record_call)
	{
		print_call_array();
	}
	free(namelist);
	return 0;
}
